FLYING

/* TODO: 気の利いた説明を書く */

UTF-16やUTF-32は要らない子なのかしら

ASCII「文字コード何よ?おいらっちASCIIなんやけど?wwwwww」
UTF-16UTF-16です。」
ASCII「・・・え・・・!?」
UTF-16「UTF-16LEです。サロゲートペアもありますよ。」*1
ASCII「・・・う、うわあ・・・ああ・・・ああああああああああ(イスから転げ落ちる)」
UTF-16「どうかしましたか?」
ASCII「ああ、あふゥッ・・・ひいいい・・ガクガク(足が震える)」
UTF-16「やだなあ、そんなにびびらないで下さいよ。ちょっとバイト数が文字数の整数倍にならないだけですから^^」
ASCII「ああ・・あ・うんっ・ああ・・・ビクンビクン(小水を漏らす)」
UTF-16「ちなみに異体字セレクタもありますよ。」*2
ASCII「あんっ!ああん・・らめ・・・もうらめえ!ビクンビクン(射精する)」

今までは文字セットとしてUnicodeを使う限りにおいて,ASCIIセーフであって欲しい場合はUTF-8を,OSやプログラミング言語で内部エンコーディングとして扱う場合にはUTF-32を使うのがベストだと考えていた。

前者でUTF-8を推しているのは,UTF-8がASCIIセーフであることに加えて,文字列中の適当な1バイトを読み込んだときに,それがある文字を表現するマルチバイト列の先頭バイトなのか,あるいは2バイト目以降なのかが明確に判別できる仕様になっているからだ。また,後者でUTF-32を推していたのは,UTF-16サロゲートペアのために「2バイトで1文字を表現する」という目的が既に達成できないと考えていたからで,UTF-32ならばバイト数が膨らむという問題はあれど,バイト数を4で割ってその文字列の文字数を知ることができ,内部エンコーディングとしてのメリットが大きいと考えていたからだ。

しかし,改めてUnicodeの仕様を見てみると,サロゲートペア以前に結合文字*3異体字セレクタの存在があり,UTF-32を使ったとしても「4バイトで1文字を表現する」という目的を達成できないことがわかった。だとすると,UTF-8に明確なメリットがある一方で,あえてUTF-16UTF-32を採用するメリットとは何なのだろう。「文字数の整数倍が文字列表現のバイト数と一致する」という幻想が崩壊した今,UTF-16UTF-32に存在意義はあるのか?

バイト数の大小という観点で言えば,UTF-8表現では日本語で使われる多くの文字が3バイトになる一方で,UTF-16表現では(常用漢字を使う限りでは)2バイトに収まるはずなので,UTF-16を採用したほうがメモリや通信量を節約できる,という意味ではメリットもあるかもしれない。

*1:U+0000〜U+FFFFに含まれない文字(BMP外文字)を表すための苦肉の策。BMP外文字は「D800H〜DBFFH」の先行2バイトと「DC00H〜DFFFH」の後続2バイトのペアで表現する。

*2:「渡邉」の「邊」のように異体字が存在する文字について,特定の異体字を親字である「邊」と異体字セレクタと呼ばれる特殊文字の組み合わせで表現する。

*3:複数Unicodeコードを並べてひとつの文字を表現する。「ふ(U+3075)」と「゜(U+309A)」を組み合わせて「ぷ」を表現するなどの例がある。アクセント文字や音符記号などでも使われている。MacからWindowsに送信したファイルの名前がおかしくなるのはだいたい結合文字の影響。最近の気持ち悪い顔文字もだいたいこいつ。