『[ 改訂新版]プログラマのための文字コード技術入門』
ソフトウェアと文字コード
ソフトウェアのエンジニア・開発者であれば、文字コードというものについて大なり小なり触れたことがあることでしょう。ソフトウェアを開発したり運用したりする上では必要になる知識です。ASCIIやシフトJIS、Unicode、UTF-8といったものがよく知られています。プログラマは、プログラムを書くたびに文字列処理という形で文字コードのデータを操作しています。
また、開発に携わらない場合でも、幅広いユーザーが文字コードを意識する機会はあります。たとえば、ソフトウェアの設定ファイルをテキストエディタで編集するときにどの文字コードで保存するかといったことや、通信ソフトウェアの送受信を指定するときにどの文字コードで送受信するといった指定には、文字コードの知識が必要になってきます。
文字コードとは
文字コードとは、大まかにいえば、文字をコンピュータで処理したり通信したりするために、文字の種類に番号を割り振ったものです。文字の形を画像としてやり取りする代わりに、「 あ」は1番、「 い」は2番、……のような番号を振って、その数値の並びを送受信することで文字列データを通信します。
これだけの説明だと、文字コードというのはとても単純なものに思えるかもしれません。実際、初期の文字コード、たとえばASCIIというコードは、7ビットの1バイトで表現されるシンプルな仕様です。ところが今日では、シフトJISだEUCだUnicodeだと様々な文字コードがあり、かつ、個々の文字コードの仕様自体も大変複雑になっています。知れば知るほど頭を抱えるのが文字コードの世界です。
文字コードの複雑化した経緯
なぜ複数の文字コードがあるのでしょうか。それは歴史的な経緯によります。
最初はASCIIという100文字弱の単純な1バイトコードでした。これはアメリカで標準化された規格であり、英語に使われる文字しか入っていません。したがってアルファベットにアクセント記号をつける欧州の言語には適しません。ましてや漢字のように何千文字もあるような文字体系は、1バイトのコードではどう見ても対応不可能です。こうした、国や地域ごとの要件に対応した文字コードを作りたいというのが、様々なコードが開発された原動力でした。
とりわけ、漢字に対応するには、2バイトコードの開発が不可欠でした。1バイトでは最大256文字しか入りませんが、2バイトあれば理論的には最大65,536文字まで入ります。2バイトコードの実用化は日本語や中国語、韓国語の情報処理にとって大きなステップでした。
さらに、過去の資産との互換性も求められます。これが文字コードを複雑化させる大きな要因です。2バイトコードができたからといって、従来の1バイトコードを捨てて全てが2バイトの世界になるわけにはいきません。プログラムのコンパイラやインタプリタなどは、相変わらずASCIIのような1バイトコードをベースとして動くわけです。そこで、1バイトコードと2バイトコードを組み合わせる技法が開発されます。よく知られているシフトJISやEUCといったコードはそうしたものの一種です。シフトJISは、日本の1バイトコードJIS X 0201と2バイト漢字コードJIS X 0208とを組み合わせて運用する方式です。EUCはASCIIとJIS X 0208の組み合わせです。
JISとして標準化された日本の2バイト漢字コードJIS X 0208は、シフトJISやEUCなどの形で大いに使われましたが、収録した文字種が必ずしも十分でなく、拡張の必要性が認識されました。
さらに、情報通信技術が発達して国際的な活動が増えると、今度は、国や地域別に作られていた文字コードをまとめて国際的な統一文字コードを作ろうということになりました。
図a 国際符号化文字集合の概念
※ 『[ 改訂新版]プログラマのための文字コード入門』第2章 図2.11より
開発された国際文字コードがISO/IEC 10646、一般にはUnicodeとして知られるものです。しかし一方で国別の規格がすでにあるわけですから、そこと互換性をどう保つかが問題になります。さらに、Unicode自体も拡張を重ねており、またUTF-16やUTF-8といった各種の符号化方式が作られ、当初の思惑から離れて非常に複雑なものになっています。
したがって、今日の文字コードを理解するためには、最新の情報だけを追っても不十分で、その背景となる過去の経緯を紐解いていく必要があるのです。
Unicodeの複雑な機構
Unicodeは単に文字数が多いというだけではなく、従来よく使われてきた文字コードにおいては一般的でなかった仕組みも持ち合わせています。
Unicodeの複雑な点の一つとして、複数の符号位置を組み合わせて1文字を表現することが挙げられます。符号位置とは、端的にいえば文字コード表の1マスです。通常は1つの符号位置に1文字が割り当てられます。しかしUnicodeには結合文字という種類の文字があり、これを使うと複数の符号位置を組み合わせて1文字を表現できます。
この例としては、欧州言語に用いられるダイアクリティカルマーク(アクセント記号等)つきのアルファベット、たとえば「ñ」のような文字があります。ベースとなる「n」の直後に合成用のチルダ記号「˜」を続けることで1文字を表現するというものです。また、日本の仮名文字の濁点・半濁点つまり「ガ」「 ぱ」なども同じやり方で表現できます。こうした表現方法をすると、ASCIIのように人が認識する1文字が必ず1符号位置によって表されるとは限らず、複数の符号位置の列を1文字として扱う必要があります。
図b 文字合成
※ 『[ 改訂新版]プログラマのための文字コード入門』第3章 図3.26より
最近では絵文字にも複数の符号位置を組み合わせて表現するものがあります。次の図のように、女性の絵文字とコンピュータの絵文字とを組み合わせて「女性の技術者」を表すような表現がUnicode絵文字に定義されています。ここでZWJ(Zero-Width Joiner)という制御文字の一種が合成表現のために使用されています。
図c ZWJで組み合わせる例
※ 画像例はTwitterに表示されるもの。『 [ 改訂新版]プログラマのための文字コード入門』第3章 図3.38より
このような表現方法は従来のASCIIやシフトJIS等のコードには無かった要素です。プログラミング上、1文字が複数の符号位置で表現されうるということを意識しないと、思わぬトラブルの元になります。
本書『[改訂新版]プログラマのための文字コード技術入門 』は、文字コードの基礎となる考え方にはじまり、ASCIIからUnicodeに至る文字コードの変遷の概観を紹介したうえで、代表的な文字コード規格を紹介し、インターネットでの扱いやプログラミング言語における実際、それによくあるトラブルなどを説明します。本書が複雑な文字コードの世界を読み解く手がかりとなれば幸いです。