『𝑩𝑰𝑮 𝑳𝑶𝑽𝑬__』についての考察

この投稿は機種依存文字を含みます。

X(旧・Twitter)で以下の投稿を見て、「このフォントどうやって出すんだ…?」と疑問を抱いたのがきっかけです。

少し前に『𝑩𝑰𝑮 𝑳𝑶𝑽𝑬__』というミーム?が流行ったときにも見かけていたのですが、あらためて気になったので色々調べてみることにしました。

この字体、どうもX独自のフォント設定などによるものではなく、もともとUnicodeに定義されている文字だということが分かりました。

ユニコード名を「MATHEMATICAL BOLD ITALIC CAPITAL」というそうで、本来は学術用・装飾用に定義されているようです。

ちなみにこういうサイトで色々変換できます。

ちなみに 𝑨 の場合はUnicodeコードポイントがU+1D468となっています。

UTF-8変換したら…

𝑨をUTF-8に変換したらどうなるのだろうと思い、まずUnicodeのエスケープシーケンスを行ったところ、\ud835\udc68と1文字から2文字?のエスケープシーケンスが得られました。

次にUTF-8にバイトコード変換を行ったところ、0xf0 0x9d 0x91 0xa8となりました。

0xd835 + 0xdc68 = 0x1b49dとなり、コードポイント0x1d468と一致しません。またUTF-8のバイトコードの上位2ビット0xf09d、下位2ビット0x91a8もエスケープシーケンスとそれぞれ一致しません。

このことに違和感を覚え、それぞれどういう関係性になっていてどのように導出できるのか?が気になって夜しか眠れなくなってしまいました。

Unicodeの追加面とサロゲートペア

ChatGPTに聞いてみたところ、補助平面(=追加面)とサロゲートペアというのがどうやらキーワードになっていそうだ、ということが分かりました。

Unicodeには通常使われる文字のほとんどが含まれる基本多言語面U+0000 ~ U+FFFFと、それ以外の追加面があるそうです。で、これをUTF-16変換する際にはサロゲートペアにする必要があるということでした。

このことは上記のWikipediaのページにも記載がありますが、文系の私的には以下のサイトが分かりやすかったかなと思います。

Unicodeコードポイント→UTF-8(バイトコード)変換

𝑨のUnicodeコードポイントU+1D468からUTF-8のバイトコードを算出してみます。

まず、上記のコードポイントを2進数に基数変換します。以下になります。

1 1101 0100 0110 1000

次の変換規則に従い、導出されたビット列を x に割り当てていきます。このとき、桁数が足りない場合は先頭(上位ビット)に 0 を足して割り当てます

※これの意味が分からなくて調べたりChatGPT先生に聞きまくってたりしました。結局理屈は理解できませんでしたが…

符号位置(16進)UTF-8のビット列(2進)
範囲1U+0000 – U+007F0xxx xxxx
範囲2U+0080 – U+07FF110x xxxx 10xx xxxx
範囲3U+0800 – U+FFFF1110 xxxx 10xx xxxx 10xx xxxx
範囲4U+10000 – U+10FFFF1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx

変換テーブルは以下を参照しました。

今回の場合、コードポイントの2進数が17ビットに対して「範囲4」の計21ビットを割り当てますので、先頭に4ビットの 0 を足して左から順に割り当てていきます。

0 0001 1101 0100 0110 1000

割り当てると、以下になります。

1111 0000 1001 1101 1001 0001 1010 1000

これを8ビットずつ16進数に変換すると

1111 0000 = 0xf0
1001 1101 = 0x9d
1001 0001 = 0x91
1010 1000 = 0xa8

となり、UTF-8のバイトコードが求まりました。

Unicodeコードポイント→UTF-16(サロゲートペア)変換

同じく𝑨のUnicodeコードポイントU+1D468からUTF-16のサロゲートペアを算出してみます。

コードポイントから追加面のオフセットを引きます。

0x1d468 - 0x10000 = 0xd468

これを2進数に基数変換します。

1101 0100 0110 1000

先頭に 0 を足して20ビットにします。

0000 1101 0100 0110 1000

上位10ビットと下位10ビットを分割し、それぞれHSG, LSGとします。

HSG = 00 0011 0101 = 0x0035
LSG = 00 0110 1000 = 0x0068

それぞれに予約アドレスの開始領域を足します。

HSG = 0x0035 + 0xd800 = 0xd835
LSG = 0x0068 + 0xdc00 = 0xdc68

となり、UTF-16のサロゲートペアが求まりました。

まとめ

UTF-8バイトコード→UnicodeコードポイントやUTF-16サロゲートペア→Unicodeコードポイントについては上記と逆の手順で算出できるはずですが、疲れたのでこの辺にしておきます。

普段はあまり気にしないところですが、せっかく気になった機会だったのでちょっと深堀りしてみました。おしまい。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日記

前の記事

Vポイント奮闘記