UTF-16 サロゲートペア
こんにちは。moriyama です。
ひさしぶりにブログを書きます。
今日は、Unicode の 16ビットコード UTF-16 のサロゲートペアのコード範囲の求めかたを書きたいと思います。
サロゲートペアとは?
まずは、サロゲートペアのおさらいをしておきます。
Unicode は当初、16ビット固定長の文字コードとしてスタートしました。16ビット長のコードでは符号化できる文字数は最大で 216 = 65536 文字まで扱える事になります。
しかし、現在 Unicode は拡張され 016~10FFFF16 までのコードを使用するようになっています。10FFFF16 は 21 ビットあれば表現できますが、221 - 1 = 1FFFFF16 でない事にご注意ください。
UTF-32 は 32ビットコードで符号化するため、10FFFF16 までのコードをそのまま扱えます。UTF-8 では 016~7F16 までを 1 バイトコード、8016~7FF16 までを 2 バイトコード、80016~D7FF16 と E00016~FFFF16 までを 3 バイトコード、1000016~10FFFF16 までを 4 バイトコードで扱うことができます。
UTF-16 は 16ビットコードで符号化されているため、そのままでは 1000016以上のコードを使えません。
そこで、D80016~DBFF16 (上位サロゲート) のコードは直後の 16 ビットコード DC0016~DFFF16 (下位サロゲート) との組で 1000016~10FFFF16 を 16 ビットコード 2 つで符号化できるようにしました。この上位サロゲートと下位サロゲートの組をサロゲートペアと呼んでいます。
サロゲートペアはあくまでも UTF-16 の時に使うもので UTF-32 や UTF-8 ではサロゲートペアは使ってはいけませんません。UTF-16 から UTF-32 や UTF-8 へ変換する際には、ご注意ください。
UTF-16 から UTF-8 への変換で、サロゲートペアをそのまま UTF-8 化してしまったものは、CESU-8 として区別されています。正当な UTF-8 としては受け付けらずトラブルの元となりますから情報交換の際には、CESU-8 を使わないようにしなければなりません。
サロゲートペアのコード範囲の求めかた
私はサロゲートペアのコード範囲を覚えてもすぐに忘れてしまうので次のようにしてコード範囲を求めています。
1000016 の UTF-16 のコード値を使って次のように調べる事ができます。
$ perl -Mutf8 -Mencoding=utf16le -e 'print "\x{10000}"' | od -tx2
0000000 d800 dc00
0000004
D80016 が上位サロゲートの下限値、DC0016 が下位サロゲートの下限値になります。上位サロゲートの上限値は下位サロゲートの直前までなので DC0016 - 1 で DBFF16 となります。
下位サロゲートの上限値は下位サロゲートの下限値 + (上位サロゲートの上限値 - 上位サロゲートの上限値) で求まり DC0016 + (DBFF16 - D80016) = DFFF16 となります。
| 下限値 | 上限値 | |
|---|---|---|
| 上位サロゲート | D80016 | DBFF16 ← DC0016 - 116 |
| 下位サロゲート | DC0016 | DFFF16 ← DC0016 + (DBFF16 - D80016) |
確認
求めた値があっているか確認してみましょう。
まずは下限値
$ perl -e 'print pack("v*", 0xd800, 0xdc00)' | od -tx2
0000000 d800 dc00
0000004
$ perl -e 'print pack("v*", 0xd800, 0xdc00)' | iconv -f utf-16le -t utf-32le | od -tx4
0000000 00010000
0000004
次は上限値
$ perl -e 'print pack("v*", 0xdbff, 0xdfff)' | od -tx2
0000000 dbff dfff
0000004
$ perl -e 'print pack("v*", 0xdbff, 0xdfff)' | iconv -f utf-16le -t utf-32le | od -tx4
0000000 0010ffff
0000004
問題ないようです。
最後に、Unicode を扱うソフトウェアを開発する場合は、http://www.unicode.org/ を調べることをお忘れなく。
Unicode 5.1.0 は 2008年4月4日(今日)、リリース予定となっていますね!




コメント