サロゲートペア
UTF-8やUTF-32にはサロゲートペアという概念はない
仕組み
Unicode の範囲 U+D800〜U+DFFF(約2,048個) を「通常の文字には使わない特殊領域」として予約する code:_
U+0000 ─────────┐
│ │ 通常の文字(BMP)
U+D7FF ─────────┤
U+D800 ─────────┐
│ │ high surrogate (1024個) ←ペアの「前半」専用
U+DBFF ─────────┤
U+DC00 ─────────┐
│ │ low surrogate (1024個) ←ペアの「後半」専用
U+DFFF ─────────┤
U+E000 ─────────┐
│ │ 通常の文字
U+FFFF ─────────┘
ここを下記2つを組み合わせて1文字を表現する
U+D800〜U+DBFF
U+DC00〜U+DFFF
結論: D83D DE00
求める流れ
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
わかりやすい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 以上の文字を表すために考え出された仕組みが サロゲートペア です。
JavaScriptで確認
code:js
"😀".length // 2 ← 2つのcode unitとしてカウントされる
"😀".charCodeAt(0) // 55357 (= 0xD83D) ← high surrogate
"😀".charCodeAt(1) // 56320 (= 0xDE00) ← low surrogate