2024/04/17 更新
この記事は、自作OS Advent Calendar 2017の 12/8 の記事として書かれました。
IT 系のニュースサイトでも、未だに日本語の漢字や仮名のことを 2 バイト文字と呼んでいる記事が散見されます。
2017 年現在、UTF-8 という Unicode の符号化方式が主流で、日本語の漢字や仮名は 3 バイト~ 4 バイトで表現されることが多く、後述する結合文字や異体字セレクタのようなものまで含めると、さらにバイト数は増加します。日本語の漢字や仮名を 2 バイト文字と呼ぶことは適切ではありません。
Unicode の規格が始まったばかりの頃は、世界の文字を 2 バイトで表現出来ると考えられていたようです。UCS-2 と呼ばれていました。
UCS-2 では文字を表現する領域が足りなくなり、サロゲートペアと呼ばれる 4 バイトの領域を増やして、2 バイトまたは 4 バイトの可変長の符号化方式である UTF-16 が考案されました。
UTF-8 は ASCII の上位互換になっていて、ASCII のコード範囲は同じバイト値です。それ以外のコード範囲は、2 バイト~ 4 バイトで表現されます。UTF-16 と同じコード範囲に文字が割り当てられています。
UTF-32 は、4 バイトで Unicode のコード範囲を表現する符号化方式です。UTF-8 や UTF-16 のように可変長で表現する符号化方式ではありません。しかし、4 バイトで表現しているのは、あくまでも符号位置であり、文字と等価ではありません。符号位置は、文字以外を割り当てることもあるコード番号なのです。この点について少し詳しく、次で説明したいと思います。
結合文字と呼ばれる仕様があり、複数の符号位置を合成することで 1 文字になるというものです。日本語でも仮名と、濁点や半濁点を合成して 1 文字とする結合文字があります。
また、意味上は同じ文字で細部の形が異なる文字のことを「異体字」と呼びますが、文字の後に続けて置くことで字形を指定する符号位置のことを「異体字セレクタ」と呼びます。
結合文字や異体字セレクタの存在により、UTF-32 向けのプログラムを開発する場合でも、4 バイトの固定長で処理を正しく記述することは出来ないと言えるでしょう。
符号化方式が異なるだけで、UTF-8 や UTF-16 でも結合文字や異体字セレクタを扱えるようにするには、複数の符号位置を 1 文字として処理出来ることが必要になります。