Webエンジニアのブログ

「プログラマのための文字コード技術入門」を要約したのでメモ

Amazonを眺めているとプログラマのための文字コード技術入門の新改訂版が出版されていた。

改定以前の本は紙で読んだことはあるんだけど、中身をすっかり忘れている事に気づき、Kindle版を要約してみた。うーん、やはり読みながらアウトプットすると記憶に残りやすいし、見返すときにも便利。

以下要約。

文字とコンピュータ

文字を重複なく集めた集合を文字集合と呼ぶ。例えば、ラテン・アルファベットの大文字・小文字を集めたものは一つの文字集合である。

文字集合を定義し、その集合の各文字に対応するビット組み合わせを定めたものが文字コードまたは符号化文字集合である。文字に対応するビット値自体を文字コードと呼ばれることもあるが、後者をコード値と呼ぶ。

文字コードと符号化文字集合はほぼ同じ意味だが、文字コードの方は少し広い(曖昧な)意味で使われる。文字コードは「文字符号化号式」と呼ばれる、符号を計算によって変形したり、複数の符号化文字集合を組み合わせたりすることの意味を指すこともある。

文字コードの変遷

最もシンプルな文字コード

最も基本的な文字コードは、1960年台にアメリカの規格として開発されたASCII(American Standard Code for Information Interchange)である。ASCIIは7ビットの1バイトコードで、全部で128の符号位置がある。ただし全てを文字に割り当てるのではなく、一部は制御文字に割り当てられている。

ASCIIはアメリカで開発されただけあって、他国では自国の通貨記号などが使えなかった。そのためASCIIの一部の文字や記号を別のものに取り替えて文字コードを作るということが行われた。各国版のための基本的な枠組みはISO/IEC 646という国際規格において用意された。日本版はJIS X 0201として標準化されている。

文字コードの構造と拡張方法を定める

7ビットのASCIIに始まった文字コードを拡張するために確立されたのがISO/IEC 2022である。これにより8ビットコードや2バイトコードの表現が可能になり、複数の符号化文字集合を組み合わせることが可能になった。8ビットコードは第8ビットも用いる文字コードであり、2バイトコードは2つのバイトで1文字を表す文字コードである。

複数バイトの符号化文字集合を複数バイト文字集合と呼び、2バイトや3バイトを併せて文字の表現に用いるものである。2バイトであれば94×94で最大8836文字を収録できる。2バイトで表現される文字を2バイト文字、マルチバイト文字と呼ぶことがある。

2バイト符号化文字集合の実用化

ISO/IEC 2022に則った2バイト符号化文字集合は1970年代後半から実際に実用化され始めた。その先駆けとなったのが、日本のJIS X 0208である。JIS X 0208はラテン文字や算用数字、漢字などを表現できるが、バイト単位で見たときには既存の1バイトコードの上位互換ではない。ASCIIでは1バイトで表せても、JIS X 0208では2バイトになってしまう。

そのため従来の1バイトコードで表現できる文字は1バイトで扱い、追加で2バイトの文字も扱えるように、Shift_JISやEUC-JP、ISO-2022-JPなどの符号化方式が普及した。

1バイト符号化文字集合の広がり

必要な文字数が比較的少ないヨーロッパの言語の文字コードとしては、8ビットの1バイトコードが普及していた。しかし1バイトではヨーロッパ全域の文字を表すことができないため、各地域ごとの1バイトコードがいくつも開発された。

例えばISO/IEC 8859-1という文字コードは、西ヨーロッパ各国の言語(英語、ドイツ語、フランス語、イタリア語など)を表すことができる。この文字コードはLatin-1という通称でも知られており、現在でも欧米を中心に使われている。

しかし8ビットには限界があったため、西ヨーロッパと東ヨーロッパの文字を一つのテキストに混在させることはできなかった。

国際符号化文字集合の模索と成立

世界中の文字を一つの文字集合に収めた文字コードを作るため、ISO/IEC 10646の開発が開始された。これはISO/IEC 2022に基づいてこれまでに開発されてきた符号化文字集合との互換性を極力保とうしたもので、基本的に4バイトで1文字を表す符号である。

ところが同時期のコンピュータ関連企業のグループがUnicodeという国際文字コード仕様を開発し始めた。こちらは既存の規格との互換性が乏しく、16ビットの固定幅で1文字を表現するものだった。ISOと企業グループで同じ目的の異なる国際文字コードが並立することは望ましくないため、統合する作業が進んだ。この結果、もともとのISO/IEC 10646の案は変更され、Unicodeの設計が取り入れられる形になった。

この結果、4バイトという建前は残しつつ、16ビット固定というUnicodeの設計を反映して下位2バイトの領域の中にすべての文字を配置した、実質的に2バイトの符号化文字集合として作成された。10646の最初の版が制定されたのは1993年のことである。

Unicodeの拡張と各種符号化方式の成立

ほどなくして16ビットすなわち65536文字では、世界中の文字を収めるには不十分であることが明らかになり、Unicodeの16ビット固定という方針が破綻した。そのためISO/IEC 10646ではまったく仕様されていなかった上位2バイトに文字を配置する必要が生じた。そこで従来の16ビットのUnicodeと互換性を保ったまま、拡張できる手段が開発された。

Unicodeの中で文字が割り当てられていない未使用の領域の16ビットの符号単位を2つ並べることで、拡張部分の1文字を表現する符号化方式をUTF-16という。またASCIIとバイト単位で互換となるよう計算式によって変形を施したUTF-8という可変長の符号化方式が開発された。

代表的な符号化文字集合

UnicodeとISO/IEC 10646

ISO/IEC 10646は規格名称をInformation technology - Universal Coded Character Set(UCS)という。 UCSはもともと4バイトの符号であり、また2バイトのサブセットの符号がある。この4バイトの符号をUCS-4と呼び、サブセットの2バイトの符号をUCS-2という。

UCS-4を構成する4バイトはそれぞれ群(group)、面(plane)、区(row)、点(cell)に対応する。群は16進数で00から7Fまでの128、面・区・点はそれぞれ00からFFまでの256あります。 群00の面00がUCS-2に相当する面であり、この面を基本多言語面(Basic Multingual Plane、BPM)と呼ぶ。BMPはもともとのUnicodeにあたる。

代表的な文字符号化号式

文字コードはもともと単純な符号化文字集合のみだけで運用できていたが、符号化文字集合を複数組み合わせたり、計算で変形したりすることが行われるようになった。つまり、文字符号化方式は、後付けで生まれたものである。

Unicodeの符号化方式

現在のUnicodeは、整数で表現される100万あまりの符号位置を8ビット単位、16ビット単位、32ビット単位といったさまざまな符号化方式で表現するという形になっている。それぞれUTF-8UTF-16UTF-32という名前が付いている。UTFは、UCS Transformation Formatの略である。

UTF-16

UTF-16は16ビットの符号単位を用い、BMPの文字は符号単位一つによって表し、BMP以外の面の文字は符号単位2つの組み合わせによって表す符号化方式である。

UTF-16ではBMP以外の面の文字を表すために、サロゲートペアという仕組みを用いる。サロゲートペアはBMPの中の文字の割り当てのない符号位置2つを用いて、BMP外の面の符号位置を指すものである。U+D800~U+DBFFを上位サロゲート、U+DC00~U+DFFFを下位サロゲートといい、この組み合わせによって1つの符号位置を表す。

UTF-32

UTF-32はUCS-4と同じで、各符号位置が4バイト固定幅で表現されている。現状ではあまり使われていない符号化方式である。

UTF-8

UTF-8は8ビット単位のUnicodeの符号化方式で、ASCIIと互換性があることから広く使われている。1つの符号位置の表現に1バイトから4バイトまでの可変長で表す。かつては最大6バイトまでであったが、現在はサロゲートで表せる範囲以外の領域は符号空間から削除されたため、最大4バイトに収まっている。

インターネットと文字コード

電子メールと文字コード

電子メールは当初ASCIIしか使うことができなかった。しかし多言語を扱う仕組みや、画像や音声を扱う仕組みが必要になり、MIME(Multipurpose Internet Mail Extensions)という規格が開発された。

MIMEではヘッダのContent-Typeに扱う文字コードを指定する。またメールは7ビットしか扱えないため、UTF-8など8ビットを用いるものはquoted-printablebase64のいずれかの符号化を適用して、7ビットに収まるよう変形しなければならない。符号化した場合はContent-Transfer-Encodingでその情報を示す必要がある。

quoted-printableは第8ビットが1になるコード値を0以下になるよう変形を施す符号化である。Latin-1のような多くの文字はASCIIの範囲で済むが、ときどき8ビットコードを扱う必要がある場合に有用となる。base64はデータ全体を変形する符号化であり、1バイトあたり6ビットまでの情報しか含めないように変形する。データのビット列を先頭から6ビットずつ取り、各ビットをASCIIの1文字に対応させて表す。符号化のデータは元のデータよりも約1.33倍に増える。

添付ファイルとして送る画像ファイルのバイナリファイルも、base64に符号化されたうえ送信される。

Webと文字コード

HTMLではUnicodeの文字なら何でも使える。キーボードから入力できないなどの理由で直接書くことのできない文字については、文字参照という方法で間接的に記すことができる。文字参照でを表す場合、UCS-4の10進である山、UCS-4の16進であるのように表すことができる。

©を表す場合は、©で表すことができる。これは文字コードの値でなくcopyという名前によって©を参照しており、これを実体参照と呼ぶ。HTMLでは、copyという名前は©を表すなどの定義があるため、©と書けば©と同じ効果が得られる。


{ "name": "hareku", "job": "Web Engineer" }