2025-10-09

Unicode符号位置からUTF-16サロゲートペア表現計算する

𩸽(ほっけ)のUnicode符号位置はU+29E3D。これをUTF-16で表すとする。

U+10000以上の符号位置文字UTF-16で表す場合サロゲートペアによって表現される。


まず、Unicode符号位置を表す「U+n」のnに対して、0x10000を減算する。

𩸽はU+29E3Dだから、0x10000を減算すると、nは0x19E3Dとなる。

(なお、Unicode符号位置が0x10000未満である場合は、それは16ビットであり(なぜなら0x10000未満であるとは、最大でも0xFFFFだから)、2バイト表現される。これはBMP範疇であり、サロゲートペア表現(BMP外の文字表現)の出番はない。)

(また、0x10000以下の符号位置のうち、Unicode符号位置U+D800~U+DFFFはサロゲートペア用に確保された符号位置領域であり、この領域内の一符号位置対応する文字は無い。)


0x19E3Dを、20桁の2進数変換すると、

$ echo "obase=2; ibase=16; 19E3D" | bc
11001111000111101
↓(不足した桁をゼロで埋める)
00011001111000111101

となる。



この20けた(0001100111 1000111101)のうち、

①上位10桁(0001100111)に対して0xD800(1101100000000000)を足す。これを上位サロゲートと呼ぶ。

1101100000000000
      0001100111
↓
1101100001100111


②下位10桁(1000111101)に対して0xDC00(1101110000000000)を足す。これを下位サロゲートと呼ぶ。

1101110000000000
      1000111101
↓
1101111000111101


③上位サロゲートと下位サロゲートの組み合わせ(1101100001100111 1101111000111101)が、UTF-16サロゲートペア表現のものである

$ echo "obase=16; ibase=2; 11011000011001111101111000111101" | bc
D867DE3D


求めた結果が正しいのか、unicodeコマンド確認する。

$ unicode 𩸽
UTF-16BE: d867de3d
(※"BE"とはbig-endianの略であり、「この16進表現は左から上位バイトとして読みますよ」という意味)


Unicodeにおいて、本来文字は16bit、つまり65535文字で十分表現できるはずだった。

しか中国古代漢字などの文字も収録しようとすると、とても16bit程度では表現できないことが分かった。

そこで、UTF-16という符号方式においては、サロゲートペアという工夫を使うことで、10万以上の文字を扱えるように仕様を整えた。


正確にいうと、2byte(16bit)では65536文字表現できる。

ところで、0xD800~0xDFFF(2048の符号位置)はサロゲートペア用に確保されているため、特定文字符号位置としては利用できない。

その一方、サロゲートペアによって20bit分(1048576文字分)の符号位置を確保できたため、UTF-16では、

$ echo $((65536-2048+1048576))
1112064

111万文字ほど表現できる。

記事への反応(ブックマークコメント)

ログイン ユーザー登録
ようこそ ゲスト さん