サロゲートペア
わかりやすいmrsekut.icon
gpt-5.icon
1. 背景
Unicode はもともと「16ビット(2バイト)で世界中の文字を表す」という思想で始まりました。
16ビットで表せる範囲は U+0000〜U+FFFF(65,536文字, BMP = Basic Multilingual Plane)。
しかしすぐに「65,536 では足りない!」と判明します。
漢字の拡張
絵文字や記号
古代文字など
そこで Unicode 2.0 以降、21ビット(U+0000〜U+10FFFF) に拡張されました。
2. UTF-16 での問題
つまり 1 code unit では U+0000〜U+FFFF の範囲しか直接表せません。
U+10000 以上の文字を表すために考え出された仕組みが サロゲートペア です。
3. サロゲートペアの仕組み
特殊な領域を利用
Unicode の範囲 U+D800〜U+DFFF(約2,048個) を「通常の文字には使わない特殊領域」として予約。
ルール
1文字 = high surrogate + low surrogate の2つの code unit
例: 😀 (U+1F600)
1. まず code point から 0x10000 を引く:
0x1F600 - 0x10000 = 0xF600
2. 20ビットの値に分解:
上位10ビット: 0x3D → high
下位10ビット: 0x600 → low
3. サロゲート範囲に加算:
High surrogate = 0xD800 + 0x3D = 0xD83D
Low surrogate = 0xDC00 + 0x600 = 0xDE00
4. UTF-16 の表現 = D83D DE00
4. プログラミングでの落とし穴
code:js
"😀".length // → 2 (サロゲートペアだから2 code units)
サロゲートペアを「文字1つ」として扱いたい場合は、Array.from() や正規表現の u フラグを使う必要がある。
code:js
"😀".match(/./u).length // → 1
Python3 などは内部で code point 単位なので len("😀") → 1 となる(実装依存はあるけど論理的には code point ベース)。