本稿は、1996年に筆者が大学の所属サークルの機関誌に寄稿した記事をもとに加筆訂正したものです。(最終更新 1999.7.31)
ASCIIだけで用が足りるアメリカと違って、 私たちは日本語を扱わなくてはならないため、 より深く文字コードの問題と関わらざるをえません。 それでも、MS-DOS/WindowsやMacを使う限りでは、 ASCIIとシフトJIS(たまにJIS)を知っていれば済みますが、 UNIXやインターネットを使い始めると、 JIS・EUC・シフトJISとさまざまな日本語コードに頭を悩ませることになります。 さらに最近はUnicodeも登場し、 Windows95/NTの内部コードとして実際に使われ始めています。
その他にも、文字コードに関してはいろいろ疑問があることと思います。
こういった問題に対処するには、 文字コードに関する体系的な理解が必要となります。
なお、本稿では、とっつきにくさを避けるため、 最初のうちは未定義の用語や必ずしも厳密でない説明を用いることがありますので、 正しい理解のためには必ず最後まで読んでください。:-)
この章では、もっとも身近な日本語のコード体系について概観します。
昔(1970年代まで)は各メーカーごとにさまざまなコード体系が使われていましたが、 1978年にJIS漢字が制定されてからは、 これに基づいたコード体系が完全に主流となりました。
インターネットで日本語のメールやネットニュースに使われているコード体系です。
- 制御コード
- 0x00〜0x1F、0x7F
- ASCII文字
- 0x20〜0x7E
- 半角カタカナ
- 0x21〜0x5F (7ビット) / 0xA1〜0xDF (8ビット)
- 漢字
- 0x2121〜0x7E7E (第1バイト・第2バイトとも0x21〜0x7E)
- 補助漢字
- 0x2121〜0x7E7E (第1バイト・第2バイトとも0x21〜0x7E)
ASCIIと半角カタカナを基本とし、漢字が追加されています。 ASCIIと漢字のコード範囲が重複するため、 以下のようなエスケープシーケンスによって切り替えます。
- 漢字の開始
- ESC $ @ または ESC $ B
- ASCIIの開始
- ESC ( B または ESC ( J
補助漢字を含めることも可能であり、 補助漢字の開始のシーケンスは ESC $ ( D となります。
また、7ビットの環境では、半角カタカナもこれらと重複するため、 制御コードまたはエスケープシーケンスで切り替えます。
- 半角カタカナの開始
- SO (0x0E) または ESC ( I
- ASCIIの開始
- SI (0x0F) または ESC ( B または ESC ( J
このように半角カタカナも7ビットで表現するものを俗に7ビットJIS(JIS7)と呼び、 これに対して半角カタカナを8ビットで表現するものを俗に8ビットJIS(JIS8)と呼びます。
JISコードの利点の一つは、7ビットの伝送路でも伝送できることです。 未だに7ビットの伝送路が残るインターネットのメールやニュースで使われている理由もここにあります。 しかし、エスケープシーケンスの存在が厄介ですので、 コンピュータ内部のデータ処理ではあまり使われません。
なお、PC-98のN88日本語BASICや、 PC-PR系プリンタなどでも同様のコードが使われていますが、 エスケープシーケンスが "ESC K" と "ESC H" という独自のものになっています。 これは通称NEC JISと呼びます。
DOS/WindowsやMacなどでおなじみのコード体系です。 一部のUNIX(NEWS-OS、HP-UXなど)でも採用されています。 その起源は、日本最初の16ビットパソコンである三菱Multi16にさかのぼります。 Multi16にCP/M-86の日本語対応版を搭載するにあたって、 処理の容易なコードとしてマイクロソフトなど数社が策定したのがシフトJISです。 MS漢字コードともいいます。
- 制御コード
- 0x00〜0x1F、0x7F
- ASCII文字
- 0x20〜0x7E
- 半角カタカナ
- 0xA1〜0xDF
- 漢字
- 0x8140〜0x9FFC、0xE040〜0xFCFC
(第1バイト: 0x81〜0x9F、0xE0〜0xFC
第2バイト: 0x40〜0x7E、0x80〜0xFC)
8ビットパソコンで広く使われていたASCIIと半角カタカナをそのまま継承し、 なおかつJISコードのようなエスケープシーケンスを使わずに漢字を混在させるために、 所定の計算式によってJIS漢字コードを変換しています。
漢字の第1バイトはASCIIや半角カタカナと重複しないように配置されており、 第1バイトを見ただけで文字種がわかるようになっています。 漢字の第2バイトについても、 区切り文字として使われることの多いASCIIの0x20〜0x3Fや、 制御コードである0x7Fと重複しないようになっています。 また、テキスト画面上ではASCIIや半角カタカナと漢字の幅の比率は1:2であることが多いですが、 文字コードのバイト数もこれと同じく1:2になっています。 このような特長のため、特別にシフトJISに対応していないシステム上でも なんとか日本語を通せる場合が少なくありません。
欠点としては、 コード空間に余裕が少なく拡張性に乏しい (例えば、補助漢字を入れるスペースがない)こと、 第2バイトに含まれる0x40〜0x7Eのコード (特に、ASCIIのバックスラッシュにあたる0x5C)が問題となる場合があること、 MSBが落ちたときの復元が困難なこと、などがあげられます。
UNIXの日本語環境でよく使われるコード体系です。 EUCはExtended UNIX Codeの略で、 UNIXの多言語対応の一環として制定されました。 EUCには日本語EUCの他に中国語EUC、韓国語EUCなどもあります。 日本語EUCのことをUJIS(Unixized JIS)とも呼びます。
- 制御コード
- 0x00〜0x1F、0x7F
- ASCII文字
- 0x20〜0x7E
- 漢字
- 0xA1A1〜0xFEFE (第1バイト・第2バイトとも0xA1〜0xFE)
- 半角カタカナ
- 0x8EA1〜0x8EDF
- 補助漢字
- 0x8FA1A1〜0x8FFEFE (第2バイト・第3バイトとも0xA1〜0xFE)
JISやシフトJISとの大きな相違点は、 半角カタカナが冷遇されていることです。 JIS漢字コードの各バイトのMSBを1にすることにより漢字を導入したため、 これと重複する半角カタカナは補助的な扱いとなり、 0x8Eのプレフィクス付きの2バイトコードになっています。 また、0x8Fのプレフィクスにより補助漢字も表現でき、これは3バイトになります。
特長としては、エスケープシーケンスがない、 第1バイトを見ただけで文字種がわかる、 漢字の第2バイトがASCIIと重複しない、 ASCIIと漢字のバイト数の比率が文字の幅と一致する、 などシフトJISと類似した点に加えて、 JISとのコード変換が容易なことがあげられます。
ただし、バイト数は半角カタカナや補助漢字まで考慮すると複雑となります。 事実、EUCを採用したシステムでも、補助漢字までサポートしている例は非常に少なく、 半角カタカナのサポートもつい最近まではなおざりにされてきました。 インターネットのメールやニュースでは、 現在でも半角カタカナの使用がタブーとされていますが、 これは、EUCを採用しながら半角カタカナをサポートしていないシステムが多かったためでもあります。
他の欠点としては、シフトJISよりマシとはいえ拡張性に限界があること、 結果的にシフトJISと似て非なるものとなってしまい 日本語コードの混乱を助長してしまったこと、などです。
この章は、ASCIIと、それをベースにした1バイト文字コードについて、 詳しく見ていきます。
おなじみASCIIは7ビットの文字コードであり、 その構成は次のようになっています。
コード範囲 内容 0x00〜0x1F 制御文字(control characters) 0x20 空白(SP) 0x21〜0x7E 図形文字(graphic characters) 0x7F 制御文字DEL(delete)
制御文字とはいわゆるコントロールコードのことです。 図形文字というと●とか▲とかハートマークとか罫線とかを思い浮かべるかもしれませんが、 そうではなくて、制御文字に対して、 アルファベット・数字・記号などの目に見える形をもった普通の文字のことです。 空白は制御文字とも図形文字ともみなすことができます。 個々の制御文字や図形文字の詳細については割愛しますが、 図形文字で特に注意を要するのは次のコードです。
0x5C バックスラッシュ「\」(≠円記号) 0x7C 縦棒「|」(≠破線) 0x7E チルダ「〜」(≠オーバーライン)
ASCIIはあくまで7ビットですので、0x80〜0xFFは含まれません。 パソコンのマニュアルなどを見ると、 0x80〜0xFFにカタカナやら何やらが入ったものを 「ASCIIコード表」と称していることが多いですが、これはまちがいです。
余談ですが、制御文字の中でDELだけ0x7Fなんていうところに飛ばされているのはなぜでしょうか? これは、データ入力媒体として紙テープを使っていたころの名残だといわれています。 紙テープでは、所定の位置に穴を空けてあるかどうかによって 2進数の1/0を区別します(SunOSのppt(6)を参照)。 1文字は7ビットですから、7つの位置の穴の有無で1文字を表します。 で、もし穴を空けるときにまちがってしまった場合、 穴をふさぐのは面倒ですので、そのまちがいを含む7ビット分全部の穴を空けて 「この字はまちがいだから削除ね」ということにしていました。 つまり、「削除」→「全ビット1」→「0x7F」というわけです。
ISO(International Standardization Organization、国際標準化機構)では、 国際的な工業規格を策定しています。 コンピュータに関係のある標準化団体はいくつかありますが、 ISOはその代表的なものの一つです。 フロッピーディスク、CD-ROM、MOディスクなどもISOの規格になっており、 機種を超えて互換を保てるようになっています。
文字コードに関してもISO規格は中心的役割を担っています。 まずはISO646という規格の登場です。 これは、もともとアメリカ/英語用の規格であるASCIIを、 他の国/言語用に一部変更できるようにしたものです。 サンプルとしてIRV(International Reference Version)というものを用意しておき、 これを各国が自国の規格として採用するとき、 その中の一部のコードに関しては違う文字を割り当ててもよい、 というふうになっています。 実際にはIRVはASCIIと同じものです(数年前までは違っていた)。
IRVのうち、文字の割り当てを変更することが認められているコードは次の12個です。 参考として、IRV(ASCII)で割り当てられている文字を併記します。
コード 文字 0x23 # 0x24 $ 0x40 @ 0x5B [ 0x5C \ 0x5D ] 0x5E ^ 0x60 ` 0x7B { 0x7C | 0x7D } 0x7E 〜
ISO 646のアメリカ版すなわちASCIIでは、これらの文字はそのままですが、 ISO 646の各国版を見てみると、これらのコードに割り当てられている文字がそれぞれ違っています。 例えば、ヨーロッパの多くの言語では、アクセント記号付きの文字が必要なので、 それらをここに割り当てています。 また、これだけでは足りない場合は、制御文字BS(backspace)を使い、 合成文字として表現することを認めています。 例えば、aに^を付けたものを表現する場合は、^ BS a となります。
ISO 646の日本版は、IRVの0x5Cを円記号に、0x7Eをオーバーラインにしたものです。 これはJIS X 0201というJIS規格になっており、 JISローマ文字集合(JIS Roman)と呼ばれています。 国産のコンピュータはたいていこれを採用しているため、 0x5Cが円記号に、0x7Eがオーバーラインになっているというわけです。 ただし、NECのPC-98とその互換機に関しては、0x7EはIRVと同じチルダになっており、 0x7CはIRVともJIS X 0201とも違う「破線」になっています。 この結果、PC-98の0x21〜0x7Eの図形文字集合は、 ISO 646のどの版とも一致しない独自のものになっています (ついでに言うと、古いマシンでは0x60が空白になっています)。
ところで、シリアルプリンタを持っている人は、 マニュアルのディップスイッチの項を見てください。 「各国文字の選択」という設定で、 日本・アメリカ・イギリス・ドイツ・スウェーデンなどの選択肢があると思います。 これはまさしくISO 646の各国版を切り替えていることに他なりません。
ISO 646のこのような仕組みは、 コンピュータのメモリや通信路が限られていた時代に、 7ビットという狭いコード空間でなんとかやりくりするためのものだったわけですが、 当然の結果として、同じコードでも各国版によって表現する文字が違ってしまうという問題があります。 JIS X 0201におけるバックスラッシュと円記号の違いはみなさんもご存じの通りです。
しかし、日本ではその程度ですからまだ我慢できますが、 上記のコードにアクセント記号付きアルファベットなどを割り当ててしまった国ではそれどころではありません。 特にCやUNIXでは上記の記号を多用しますが、 これらがすべて「ü(u-ウムラウト)」やら「é(e-アクサンテギュ)」 やらになってしまっているのです。 これではとてもCやUNIXを使ってはいられません (この問題に熱心なのはデンマークで、 これらの記号を使わずにCを記述するための代用記法トライグラフを提唱しています)。
最近は、ASCIIをもとにしたISO 8859-1(後述)などの 8ビットコードを使えるシステムが一般化したため、 7ビットでしかも一国でしか通用しないISO 646各国版にこだわる必要もなくなってきました。 そのため、ISO 646各国版は(日本を除いて)流行らなくなりつつあり、 ASCIIをそのまま使うケースが多くなっています。
ラテンアルファベットを使うヨーロッパ諸語(英独仏など)は、 ISO 646でもなんとか表現できます。 しかし、ロシア語・ギリシア語・日本語などの、 文字体系が全く異なる言語は表現できません。 かといって、アメリカ/英語/ASCIIがコンピュータ界を支配している現状を考えると、 ISO 646を排除して独自のコードを使うのは現実的ではありません。 したがって、ISO 646(またはASCII)を8ビットに拡張し、 0x80〜0xFFに文字を追加しようという考えが生まれます。
その一つが、これもおなじみJISカタカナです。 前述のJIS X 0201では、ISO 646の日本版を定めると共に、 これを8ビットに拡張し、0xA1〜0xDFにカタカナを入れました。 つまり、JIS X 0201の左半分(0x00〜0x7F)はISO 646日本版で、 右半分(0x80〜0xFF)は日本独自規格のカタカナというわけです。 当時はまだコンピュータで漢字を扱うのが容易でなかったため、 この規格は広く受け入れられました。
一方、欧米のコンピュータでも、ASCIIを8ビットに拡張して、 そこにアクセント記号付きアルファベットや罫線を入れるようになりました。
パソコンの世界では、IBM PCの普及にともなってPCのコードが有力になりました。 DOSのマニュアルにあるコードページ437、 WindowsにおけるOEMコードセットというコードです。 これの右半分には、アクセント記号つきラテンアルファベット・罫線・各種記号が入っています。 しかし、言語によってはこれでも不十分なので、 EGAやVGAでは右半分がPCG(死語)になっており、 ここのフォントを入れ換えることができるようになっています。 こうして、IBM PCのコードにはコードページと呼ばれるいくつもの変種ができました。 これらもDOSのマニュアルに載っています。 なお、MacintoshはIBM PCとはまた違った拡張コードを持っています。
コードページ 名称(言語) 文字種 437 IBM PC基本 ラテン文字 850 多言語(西欧諸語) ラテン文字 852 スラブ(東欧)語 ラテン文字 857 トルコ語 ラテン文字 860 ポルトガル語 ラテン文字 861 アイスランド語 ラテン文字 863 カナダフランス語 ラテン文字 865 北欧語 ラテン文字 869 ギリシア語 ギリシア文字 932 日本語 カタカナ(JIS X 0201)
また、ISOでもASCIIをベースとした8ビットコードの規格をいくつか制定しました。 その中でも有力なものが、ISO 8859という規格です。 これもIBM PC同様、ASCIIを左半分に持ついくつもの変種(現在10個)からなっています。
規格 文字種 言語 ISO 8859-1 (Latin-1) ラテン文字 西欧諸語 ISO 8859-2 (Latin-2) ラテン文字 東欧諸語 ISO 8859-3 (Latin-3) ラテン文字 エスペラントなど ISO 8859-4 (Latin-4) ラテン文字 ISO 8859-5 キリル文字 ロシア語など ISO 8859-6 アラビア文字 アラビア語 ISO 8859-7 ギリシア文字 ギリシア語 ISO 8859-8 ヘブライ文字 ヘブライ語 ISO 8859-9 (Latin-5) ラテン文字 トルコ語など ISO 8859-10 (Latin-6) ラテン文字 北欧語など
このうちISO 8859-1、通称Latin-1が広く使われています。 ワークステーションのコンソール画面やxtermなどで 8ビットコードを表示させると出てくるのが、このLatin-1です。 また、Windowsも「ANSIキャラクタセット(コードページ1252)」という名前でLatin-1を正式採用しました。 それ以外のISO 8859シリーズは、一応国際規格ではありますが、 それぞれの言語のコミュニティの外ではあまり目にすることはありません。
IBMの各コードページやISO 8859のそれぞれは、 ISO 646よりもずっと多くの文字を含んでいますので、適用範囲も広く、 一つのコード表を複数の国・言語で共通に使うことが可能です。 たとえば、Latin-1だけで英語・ドイツ語・フランス語など西欧の主要言語をカバーすることができます。
しかしまた、ラテン文字のコード表がいくつもあることに気がつくでしょう。 これは、アクセント記号付きラテン文字の種類が多すぎて、 一つのコード表に入り切れなかった結果です。 また、ギリシア文字のようなまったく異なる文字を入れる余地もないので、 これまた別のコード表になっています。 どうしても混在させたければコード表を切り替えるしかありません。 この問題は、8ビットというコード空間が本質的に狭すぎるのが原因であり、 複数の国や言語で共通に使えるとはいっても、 その範囲は自ずから限られてしまいます。
とくにISO 8859の場合、当初の目標では、ISO 646各国版のようなわずらわしさを避けるために、 コード空間を広げた代わりに合成文字を廃止して8ビット固定長にしたのですが、 結局は似て非なるコード表がいくつもできてしまい、 言語によって切り替えて使わなくてはならないという、 ISO 646とたいして変わらない状況に陥ってしまいました。
なお、ISOの8ビットコード(8859に限らず)は、次のような構成になっています。
コード範囲 内容 0x00〜0x1F 制御文字の領域 0x20〜0x7E ASCII図形文字 0x7F 制御文字DEL 0x80〜0x9F 制御文字の領域 0xA0〜0xFF 追加の図形文字
つまり、右半分にも左半分同様に制御文字の領域があるということです。 これについてはISO 2022の解説に譲ります。
この章では、日本語の2バイトコードの規格JIS X 0208/JIS X 0212についてみていきます。 また、これまで漠然と「文字コード」などと呼んでいたものを、 符号化文字集合とエンコーディング法という二つの概念によってより正確に理解します。
我々が普段使っている日本語の2バイトコードは、 JIS X 0208というJIS規格で規定されているものです。 この規格は、日本語文で通常用いられる文字や記号 (仮名・漢字・アルファベット・算用数字・各種記号など)を含み、 その符号を規定しています。
2バイトの符号値は、第1・第2バイトとも0x21〜0x7E(EUCでは0xA1〜0xFE、以下略)ですが、 JIS X 0208ではこの範囲の符号値を直接規定してはいません。 JIS X 0208では、第1バイトを区番号といい、第2バイトを点番号といいます。 範囲はどちらも1〜94です。 したがって、1つの区は94個の点からなり、 全体の符号空間は、1区1点から94区94点まで、94×94=8836文字分あります (94という数の根拠については、ISO 2022の解説で述べます)。 区または点番号の1〜94は、実際には0x21〜0x7Eとして表現されます。 なお、区番号と点番号をつなげて10進数4桁で表記したものを、 俗に区点コードといいます。
文字 区点番号 符号値 「 」 1区1点 0x2121(0xA1A1) 「◆」 2区1点 0x2221(0xA2A1) 「亜」 16区1点 0x3021(0xB0A1)
文字の割り当ては次のようになっています。
区 内容 1区〜2区 各種記号 3区 算用数字、ラテンアルファベット 4区 ひらがな 5区 カタカナ 6区 ギリシアアルファベット 7区 キリルアリファベット 8区 罫線素片 16区〜47区 第一水準漢字 48区〜84区 第二水準漢字
これ以外の区は文字が割り当てられておらず、未定義となっています。 しかし、実際には各メーカー等が独自に文字を割り当てている場合があります。 このような文字は機種依存文字・ベンダー固有文字などと呼ばれ、 情報交換の上で問題となっています。
JIS X 0208は、もともとJIS C 6226という名前で1978年に制定されましたが、 JIS X部門(情報処理)の新設に伴ってJIS X 0208と改められました。 さらに、1983年に以下のような大がかりな改訂がありました。
特に後の2つは深刻で、従来のJIS(旧JIS)と改訂後のJIS(新JIS)とで コードが同じなのに字体が異なるという問題を引き起こしました。 しかも、NECやIBMなどの有力メーカーが互換性維持のためになかなか新JISに移行しなかったため、 混乱が長引く結果となりました。 現在では多くのシステムが新JISに対応していますが、 依然として注意を要する問題です。
その後、1990年の改訂では2字の追加がありました。 また、1997年の改訂では、いままで曖昧だったさまざまな事項を明確に規定するとともに、 ISO-2022-JP(後述)やシフトJISなど広く使われているエンコーディング法の規定もとり入れ、 より現実に即した実用的な規格を目指しています。
JIS X 0208は広く普及していますが、 それにともなってJIS X 0208に不足している文字を扱いたいとの要望も高まってきました。 そこで、補助漢字JIS X 0212が制定されました。 JIS X 0212はJIS X 0208と類似の構成を持つ2バイトコードの規格です。 漢字だけでなく、JIS X 0208で不足していた記号やアルファベットなどの非漢字も含まれています。
区 内容 2区 各種記号 6区 ギリシアアルファベット補助 7区 キリルアリファベット補助 9区〜11区 ラテンアルファベット補助 16区〜77区 補助漢字
X 0212はX 0208とはまったく別個の規格ですので、 X 0208と併用する場合は、JISやEUCにみられるように、 X 0208とは異なった符号化をしなくてはなりません。 ただし、X 0212の非漢字はX 0208と重複しないように定められているので、 フォントを用意すれば非漢字だけむりやりX 0208にマージして使用することも不可能ではありません。
現在、JIS X 0212は、主にUNIXで使われています。 DOS/WindowsやMacなどシフトJISベースのシステムでは、 X 0212を追加する余裕がないため、ほとんど使われていません。
ASCII文字集合の中には、ラテンアルファベット・数字・記号などが含まれ、 それぞれに符号が定められています。 同様に、JIS X 0208は漢字・仮名などを含み、 やはりそれぞれ符号を割り当てています。 このように、コンピューターで扱いたい文字を集め、 個々の文字に符号を定めたものを、符号化文字集合といいます。 ただし、符号化文字集合で定めている符号は、 必ずしも最終的なビットの値(ビット組み合わせ)であるとは限りません。 例えば、JIS X 0208では「亜」の符号は16区1点であると定めていますが、 これは最終的なビット組み合わせ(0x3021など)を直接表現したものではありません。
なお、単に文字集合といった場合は、符号を定めていないことになりますが、 符号化文字集合のことを文字集合ということもあります。
上記のJIS X 0208のように、 実際のビット組み合わせを直接規定していない符号化文字集合を運用する場合には、 符号と実際のビット組み合わせとの対応を規定する必要が生じます。 また、シフトJISにおいてJIS漢字コードを変換しているように、 何らかの理由により符号を変換して実際のビット組み合わせを求めることもあります。 このように、符号化文字集合の符号と実際のビット組み合わせとの対応を決定する方法のことを、エンコーディング法といいます。 例えば、シフトJISはJIS X 0201・JIS X 0208という2つの符号化文字集合を対象としたエンコーディング法であり、 ISO 2022は世界の多くの符号化文字集合を対象としたエンコーディング法です。
符号化文字集合に対してエンコーディング法を適用することにより、 文字を表現する最終的なビット組み合わせが決定します。 ただし、符号化文字集合とエンコーディング法が一体となっていて分かちがたいものも存在します(台湾のBig-5など)。
この章では、ISO 2022という規格について解説します。 この規格は、複数の文字集合を組み合わせ、切り換えて使うための枠組みを規定したもので、 文字コード体系を理解する上でぜひ知っておく必要のある重要な規格です。
なお、ISO 2022はJIS X 0202というJIS規格にもなっています。
文字コードは一般に7ビットまたは8ビットのバイト列で構成されます。 一方、表現すべき文字のほうは、欧米でも数百字、 漢字文化圏では数千〜数万字に達します。 しかも使われる文字は言語や国によって大きく異なるため、 各国がそれぞれに文字集合を規格化しています。 すなわち、コード空間の狭さに比べて文字種ははるかに多く、 かつ多数の文字集合が存在しています。
このような状況で、さまざまな文字データを支障なく表現・交換するためには、 各国の文字集合の規格を組み合わせ、また切り換えて使うことが考えられます。 すなわち、普段必要とする文字を含む文字集合を組み合わせて運用し、 それ以外の文字が必要となったときはそれを含む文字集合に動的に切り換えます。 この枠組みを規定したのがISO 2022です。 一方、これに対して、コード空間を大きくとり、 その中にあらゆる文字を含めるという方法も考えられます。 これを実現したのがISO 10646/Unicodeです。
それでは、いよいよISO 2022の具体的な解説に入っていきましょう。
まずは7単位系(7ビット符号)から解説します。 7ビットの符号空間は0x00〜0x7Fの範囲がありますが、 この空間をインユーステーブル(in-use table)といいます。
7単位系のインユーステーブルは2つの領域に分けられます。 一つは制御文字を割り当てる領域で、C0領域といい、0x00〜0x1Fです。 残りの0x20〜0x7Fは、図形文字を割り当てる領域で、GL領域といいます。 このそれぞれの領域にどの文字集合を割り当てるかが決まれば、 各々の符号の表現する文字もめでたく決まるわけです。
文字集合の割り当ての機構は、制御文字と図形文字で異なっています。
制御文字の場合は、単に、所定のエスケープシーケンスによって、 C0領域にどの制御文字集合を割り当てるかを決定します。 これに対して、図形文字集合の割り当ては二段構えになっています。 インユーステーブルの他に、G0〜G3という4個の中間バッファが設けてあり、 図形文字集合をいずれかの中間バッファに割り当て、 それからいずれかの中間バッファをGL領域に割り当てるという機構になっています。 図形文字集合を中間バッファに割り当てることを「指示する(to designate)」といい、 中間バッファをGL領域に割り当てることを「呼び出す(to invoke)」といいます。 指示はエスケープシーケンスによって、 また呼び出しは制御文字によって行われます。
このような複雑な機構になっている理由は後ほど考えることにしますが、 この指示/呼び出しの機構がISO 2022の中核となる部分ですので、よく理解しておいてください。 インユーステーブル・中間バッファ・図形文字集合という階層構造のモデルは、 コンピューターの記憶装置におけるレジスタ・主記憶・外部記憶といった階層構造になぞらえることもできます。
なお、指示と呼び出しは独立の機能ですので、 指示した後すぐに呼び出さなくてはならないということはありません。 また、すでにインユーステーブルに呼び出されている中間バッファに対して図形文字集合を指示すると、 改めて呼び出しをしなおさなくても、即座に指示がインユーステーブルに反映されることになっています。
ここでは、ISO 2022で使える文字集合について説明します。 ISO 2022はどんな文字集合でも使えるわけではなく、 上述のインユーステーブルの構造と一致する文字集合でなければなりません。 制御文字については、C0領域が0x00〜0x1Fの32文字なので、 32文字の制御文字集合を用いることができます。 図形文字は、GL領域が0x20〜0x7Fの96文字なので、 96文字の図形文字集合を用いることができます。
ただし実際には、ASCII/ISO 646との互換性のために、 GL領域を0x21〜0x7Eの94文字に制限して、 0x20は空白文字、0x7Fは制御文字DEL(削除)として使われるのが普通です。 この場合、94文字の図形文字集合を用いることができます。 94文字集合をGL領域に呼び出すと、自動的に0x20は空白文字、0x7FはDELになります。
94文字図形文字集合の例としては、ASCII図形文字、 ISO 646図形文字(JIS X 0201ローマ文字を含む)、JIS X 0201カタカナなどがあります。 96文字図形文字集合の例としては、ISO 8859の右半分などがあります。
漢字のような文字数の多い図形文字は、 94文字/96文字集合では収容できませんので、 複数バイト文字集合として規定されます。すなわち、
となります。例えば、JIS X 0208は94×94文字図形文字集合であり、 1区1点から94区94点までの8836個の符号空間を持ちます。 ちなみに、古いISO 2022では、 複数バイト文字集合はG0にのみ指示できることになっていましたが、 現在ではこの制限はありません。
なお、96文字集合や96n文字集合をG0に指示することはできないことになっています。 G0はGLに呼び出されるべきデフォルトのバッファであると考えられるため、 ここに96文字集合が指示されていると、0x20が空白でなくなるなど問題が多いからかもしれません (GLに96文字集合を呼び出すこと自体は、G1〜G3を使えば可能です)。
上述のように、図形文字集合用の中間バッファG0〜G3をGL領域に割り当てることを「呼び出す」といいますが、これには2通りの方法があります。 一つはロッキングシフトといい、いったん割り当てたら次に割り当て直すまでずっと有効となるものです。 もう一つはシングルシフトといい、1文字分だけ臨時に呼び出しを変更するものです。 呼び出しのパターンと、それを実現する制御文字の名称を以下に示します。
呼び出しの方法 呼び出しの内容 制御文字 ロッキングシフト G0→GL SI (Shift In) G1→GL SO (Shift Out) G2→GL LS2 (Locking Shift 2) G3→GL LS3 (Locking Shift 3) シングルシフト G2→GL SS2 (Single Shift 2) G3→GL SS3 (Single Shift 3)
G0/G1のロッキングシフトはLS0/LS1でなくSI/SOという名称になっています。 また、シングルシフトはG2/G3にしかありません。
シングルシフトの制御文字SS2(SS3)が現れたら、それに続く1文字分の符号を、 G2(G3)に指示されている図形文字集合の符号として解釈します。 すなわち、後続の1文字分の符号に限って臨時に呼び出しを変更することに相当します。 なお、「1文字分の符号」のバイト数は、 G2(G3)に指示されている図形文字集合によって決まります。 必ずしも1バイトとは限りません。
ISO 2022では8単位系(8ビット符号)についても規定されています。 8単位系のインユーステーブルの構造は、7単位系との互換のために、 7単位系のそれを二つ組み合わせたような形になっています。
領域 コード範囲 内容 C0領域 0x00〜0x1F 制御文字の領域 GL領域 0x20〜0x7F 図形文字の領域 C1領域 0x80〜0x9F 制御文字の領域 GR領域 0xA0〜0xFF 図形文字の領域
指示および呼び出しの機構は基本的に7単位系と同じです。
制御文字の領域はC0/C1の2つありますが、 制御文字集合はそれぞれC0用またはC1用のいずれかと決められており、 C0用制御文字集合をC1に割り当てることやその逆はできません。 図形文字はそのような制限はなく、基本的には自由に指示し呼び出すことができます (ただし、7単位系のところで述べたように、いくつか例外的な制約があります)。
中間バッファG0〜G3は7単位系と同じですが、 インユーステーブルにGR領域が追加されたことに伴い、 呼び出しの機能が追加・変更されています。
呼び出しの方法 呼び出しの内容 制御文字 ロッキングシフト(左) G0→GL LS0 (Locking Shift 0) G1→GL LS1 (Locking Shift 1) G2→GL LS2 (Locking Shift 2) G3→GL LS3 (Locking Shift 3) ロッキングシフト(右) G1→GR LS1R (Locking Shift 1 Right) G2→GR LS2R (Locking Shift 2 Right) G3→GR LS3R (Locking Shift 3 Right) シングルシフト G2→GL/GR SS2 (Single Shift 2) G3→GL/GR SS3 (Single Shift 3)
7単位系と大きく異なるのは、GRへの呼び出しを行うLS?Rが追加されたことです (ただし、G0をGRに呼び出すことはできないことになっています)。 また、7単位系のSI/SOがLS0/LS1とわかりやすい名前に改められました。 シングルシフトはGLに呼び出すのが原則ですが、 GRに呼び出してもよい(シングルシフトに続く符号のMSBが1でもよい)ことになっています。
複数バイト図形文字集合もGRまたはGLのいずれか一方に呼び出されますので、 2バイト文字の第1バイトをGRに割り当てて第2バイトをGLに割り当てるといったようなことはできません。 7単位系との連続性を優先した結果ですが、 符号空間の有効利用という観点からは不満の残るところです。
なお、94文字集合や94n文字集合をGLに呼び出した場合は、 0x20が空白で0x7FがDELになりますが、 GRに呼び出した場合は、0xA0と0xFFは使用禁止となります。
これまでみてきたように、 ISO 2022では指示や呼び出し(ロッキングシフト、シングルシフト)といった制御機能をもっていますが、 これは実際には制御文字やエスケープシーケンスを用いて表現されます。 制御文字はC0制御文字とC1制御文字があります。 また、C0制御文字のESC(0x1B)に続いて0x20〜0x7Eの範囲の符号を並べたものをエスケープシーケンスといいます。 ISO 2022ではこれらを用いて以下のような制御機能を表現します。
ここではこのうち主なものを紹介します。
ここではISO 2022のエスケープシーケンスの一般形について述べます。 ISO 2022で規定されるエスケープシーケンスは、以下のような形をしています。
<ESC> <0個以上の中間文字...> <終端文字>
中間文字とは0x20〜0x2Fの範囲の符号であり、 終端文字とは0x30〜0x7Eの範囲の符号です。
なお、エスケープシーケンスを構成する中間文字や終端文字は単なる符号であり、 特定の文字集合の文字を表現するものではありませんが、 便宜上 ESC $ B のようにASCII文字を用いて示すことがあります。
文字集合の指示はエスケープシーケンスによって表現されます。 終端文字Ftは指示すべき文字集合を表します。
内容 シーケンス 94文字集合の指示 G0 ESC ( Ft G1 ESC ) Ft G2 ESC * Ft G3 ESC + Ft 96文字集合の指示 G0 (なし) G1 ESC - Ft G2 ESC . Ft G3 ESC / Ft 94n文字集合の指示 G0 ESC $ Ft(注) ESC $ ( Ft G1 ESC $ ) Ft G2 ESC $ * Ft G3 ESC $ + Ft 96n文字集合の指示 G0 (なし) G1 ESC $ - Ft G2 ESC $ . Ft G3 ESC $ / Ft
すでに述べたとおり、 96文字集合や96n文字集合をG0に指示することはできないことになっています。
(注) かつては複数バイト文字集合はG0にしか指示できなかったので、 この形のエスケープシーケンスが使われていました。 この制限は後に撤廃され、下に示したような一般化された形のエスケープシーケンスに改められました。 ただし、この時点で登録されていた94n文字集合(JIS C 6226, GB 2312, JIS X 0208)に限っては、 互換性のためにこの形のエスケープシーケンスを引き続き用いてもよいことになっており、 今でもむしろこちらの方が圧倒的に多く使われています。
終端文字と文字集合の対応は登録制になっており、 ECMAという組織が登録簿を管理しています。 以下にいくつか例を示します。
文字集合の区分は中間文字によって識別されるので、 終端文字が同一でも中間文字が異なれば異なる文字集合を表すことに注意してください。
JISコードで使用される指示のシーケンスは以下のようになります。
シーケンス 内容 ESC ( B G0にASCIIを指示する ESC ( J G0にJIS X 0201ローマ文字を指示する ESC $ @ G0にJIS C 6226-1978を指示する ESC $ B G0にJIS X 0208-1983を指示する
ESC ( BとESC ( Jの違いは旧JISと新JISの違いだとする説がありますが、 それは間違いです。 また、ESC ( Hを使うのも間違いです。
呼び出しの制御機能の表現は、 C0制御文字・C1制御文字・単独の制御機能と多岐にわたっています。 単独の制御機能とは、制御文字集合に含まれない制御機能を エスケープシーケンス ESC 0x60〜0x7E で表現するものです。
制御機能 符号 符号の区分 ロッキングシフト(左) SI/LS0 0x0F C0制御文字 SO/LS1 0x0E LS2 ESC 0x6E 単独の制御機能 LS3 ESC 0x6F ロッキングシフト(右) LS1R ESC 0x7E 単独の制御機能 LS2R ESC 0x7D LS3R ESC 0x7C シングルシフト SS2 0x8E C1制御文字 SS3 0x8F
ところで、シングルシフトがC1制御文字で表現されていますが、 これでは7単位系で表現できませんね。 実は、7単位系でもC1制御文字を表現する方法があるのです。 7単位系でC1制御文字を表現するには、 C1領域0x80〜0x9Fの代わりにエスケープシーケンス ESC 0x40〜0x5F を使うことになっています。 したがって、7単位系のシングルシフトは以下のようになります。
制御機能 符号 符号の区分 シングルシフト SS2 ESC 0x4E C1制御文字 SS3 ESC 0x4F
以上、ISO 2022の主要部分をみてきました。 これだけでもISO 2022が非常に複雑で多様な規格であることがわかってもらえたと思います。 このような複雑な規格のフルセットを実装・運用することは現実的ではありません。 むしろ、ニーズに応じて適切なサブセットを定めて運用するのが現実的でしょう。
指示や呼び出しは、情報交換当事者同士の合意があれば省略できることになっています。 たとえば、多くとも4個の文字集合で足りるようなシステムでは、 使用する文字集合をあらかじめG0〜G3に指示してあることにすれば、 呼び出しだけで文字集合を切り換えることができます。 8単位系で文字集合が2個までであれば、呼び出しすら必要ありません。 一方、多くの文字集合を必要とするシステムでは、 呼び出しを固定して指示を切り換えるのが適切でしょう。
このように、とくに図形文字集合の扱いにおいてさまざまなサブセットを構成できるようになっているため、 全体としてはおおげさとも思えるほどの規模の規格になっているといえます。
この章では、ISO 2022の実例について解説します。
EUCはISO 2022に準拠したエンコーディング法です。 日本語EUCを例にとって説明します。
EUCではX 0208は第1バイトと第2バイトのMSBが1になりますが、 これは単にASCIIと区別するために適当にそうしたのではなく、 ISO 2022の枠組みに沿って符号化した結果というわけです。 カタカナや補助漢字に付く0x8E/0x8Fのプレフィクスも、 ISO 2022のシングルシフトに由来しています。
EUCの一般的な構成として、 ASCII(またはISO 646)を含めて4つまでの文字集合を扱うことができます。 これらはG0〜G3に指示されています。 特に、G0にはASCII(ISO 646)、G1にはその言語でもっともよく使う文字集合(ASCII以外)が指示されており、 これらはそれぞれGLとGRに呼び出されています。 指示および呼び出しは固定されており、 エスケープシーケンスやロッキングシフトで変更されることはありません。 さらに、補助的に用いる文字集合をG2とG3に指示することができ、 これらはシングルシフトによって呼び出されます。 指示・呼び出しが固定なので、文字列を解釈または生成する際、 現在どの文字集合が指示されているかといったような「状態」情報を保持する必要がない(stateless, modeless)ことが大きな特徴です。
なお、通常EUCと呼んでいるものは、 正確には情報交換用のEUC packed formatという形式で、 文字集合によって1文字のバイト数が変化します。 EUCには内部処理用のEUC 2-byte complete formatと呼ばれる形式もあり、 これは1バイト文字も2バイト文字もすべて2バイトで表現し、 第1バイトと第2バイトのMSBにより4つの文字集合を区別します。 ISO 2022には準拠していません。
JIS(漢字)コードという俗称は、次の二つの意味で使われています。
たとえば、「愛という字のJISコードは3026だ」といった場合は前者ですし、 「このHTMLファイルはJISコードを使っている」といった場合は後者です。 シフトJISや日本語EUCについても同じことがいえます。
第1章で説明した「JISコード」は後者です。 今後はこれをJISエンコーディングと呼ぶことにします。 これは典型的なISO 2022準拠のエンコーディング法です。
とくに、JISエンコーディングの7ビット版は、 日本のインターネットの母体となったJUNETというネットワークにおいて、 日本語メッセージ(メール、ニュース)の交換のために使われ、現在に至っています。 そのため、時にJUNETコード(Muleの*junet*)とも呼ばれます。 また、ISO-2022-JPという名前でRFC 1468に定義されています。
JISエンコーディングの特長は、7ビット環境でも使えることだけでなく、 サポートする文字集合をいくらでも増やせること(使いたい集合をG0に指示するだけでよい)です。 ISO-2022-JPではASCII・X 0201ローマ文字・X 0208(旧/新)だけに限定していますが、 これの拡張であるISO-2022-JP-2 (RFC 1554)では、 補助漢字や中国・韓国のコードも追加されています。 また、ISO 8859もG2に指示して使えることになっています。
このエンコーディング法は「JIS」と呼ばれていますが、 これだけがJIS規格から導かれる唯一のエンコーディングというわけではなく、 混乱を招きやすい名称です。 また、ISO-2022-JP・ISO-2022-JP-2・Muleの*junet*・8ビットJISなどいくつかの流儀があり、 使える文字集合やX 0201カタカナの扱いなどが微妙に異なります。 これらをまとめて考えると、 JISエンコーディングとは「必要とする文字集合を随時G0に指示する」という原則からなる、 ゆるやかな不文律のようなものと考えるのが妥当でしょう。
シフトJISは言うまでもなくISO 2022非準拠です。 第1章でシフトJISの具体的な欠点をいくつかあげましたが、 それらはすべて「ISO 2022に準拠していない」という点に集約されます。 たしかにシフトJISは巧妙に設計されており、 日本語処理の黎明期においてカタカナから漢字への円滑な移行を促した役割は評価すべきですが、 アドホックな業界標準としての拡張性のなさはいかんともしがたく、 今後の国際化・多言語処理の流れに対応できるものではありません。
なお、JIS X 0208-1997ではシフトJISの規定がとり入れられました。 この中で、シフトJISのX 0201カタカナは将来廃止して、 そのコード空間を漢字の拡張にあてる旨の方向性が示されています。
ISO 8859やJIS X 0201などは、それだけで完結した8ビットコードの規格ですが、 ASCII(ISO 646)ともう一つの追加文字集合をISO 2022によって組み合わせたものとみることもできます。 X 0201については上記のJISエンコーディングの説明でカバーしましたが、 ISO 8859については次のようになります。
これを拡張し、G0/G1に各種文字集合を呼び出せるようにした多言語エンコーディング法が、 X11R5の国際化機能で採用されました。 Compound Text (Muleの*ctext*)と呼ばれます。
C0の制御文字集合はいくつかありますが、 普通に使われているのはISO646(ASCII)のそれでしょう。 これはいまさら説明するまでもなく、我々がいつも使っているものです。 それに比べて、C1の制御文字というのはなじみが薄い気がします。 SS2 (0x8E)とSS3 (0x8F)はISO 2022で出てきましたが、 これ以外で広く使われているものがあるのでしょうか?
実は、あるのです。MS-DOSやxtermで「画面制御用ANSIエスケープシーケンス」と呼ばれているものです。 これは、ISO 6429 (ANSI X3.64, JIS X 0211)に規定されているC1集合に準拠しています。 ISO 2022の説明で、「C1集合の制御文字(0x80〜0x9F)をESC 0x40〜0x5Fで表現することができる」というのがありましたね。 ANSIエスケープシーケンスというのは、 ANSI X3.64のC1集合をエスケープシーケンスで表現したものだったのです。
例えば、この規格の0x85に、復帰改行を行うNEL(next line)という制御文字があります。 これをエスケープシーケンスで表現するとESC 0x45、つまりESC Eとなります。 DOSのマニュアルなどでESC Eを確認してみてください。
また、同じく0x9BにはCSI(control sequence introducer)というのがあります。 これはESC 0x5B、つまりESC [となります。 ESC [といえば、画面消去・カーソル移動・属性変更など、 さまざまなエスケープシーケンスのプレフィクスですね。 CSIで始まるこれらのシーケンスは、制御シーケンス(control sequence)と呼ばれています。 制御シーケンスは終端文字によってさまざまな機能があり、 パラメータをとるものもありますが、 これらはすべてISO 6429で規定されています。
この章では、日本語以外に2バイト文字を用いる、 中国語・韓国語の文字コード体系について解説します。
中国本土の国家規格はGB(「国家標準」)といい、 2バイト文字コードの規格も簡体字・繁体字それぞれにいくつか定められています。 そのうち最もよく使われるのが、GB 2312という簡体字の規格です。 構成はJIS X 0208とよく似ており、次のような特徴をもちます。
実際にはGB 2312はGRに呼び出されてEUCとして使われるケースが多いようです。 ちょうど日本語EUCのG0・G1と同じような形になります。
ただし、インターネットのメールやニュースでは8ビットデータの通過が必ずしも保証されませんので、 alt.chinese.textではHz(Hanzi=漢字)とよばれる独自の7ビットエンコーディングを用いています。 Hzでは、GB 2312漢字の開始シーケンスとして~{を、 ASCIIの開始シーケンスとして~}を使います。
台湾の有力メーカー5社が中心となって策定したのがBig-5と呼ばれるコードです。 メーカーによって独自拡張がありますが、基本的な部分は以下のようになっています。
コード空間はシフトJISと似ていますが、 シフトJISが半角カタカナのせいで割を食っているのに対して、 そのような制約がない分だけ文字数が多くなっています。 シフトJISと本質的に違うのは、シフトJISがJIS X 0208を元にしたエンコーディング法であるのに対して、 Big-5は文字集合とエンコーディングが一体となっている点です。 Big-5は台湾や香港で広く使われています。 また、alt.chinese.text.big5など一部のニュースグループでも使われています。
Big-5が広まった結果、これをもとにISO 2022準拠の規格が作られることになりました。 台湾のCNS 11643といい、942文字集合7個からなる膨大な規模の規格です。 それぞれを「字面」と呼び、第1・第2字面にBig-5の文字を収容し、 第3〜第7字面はそれ以外の特殊な漢字を収容しています。 第1・第2字面の配列は基本的にBig-5を踏襲していますが、 Big-5の漢字配列の誤りを正しているため、順序は微妙に違います。 また、後ろの方の字面になると、まるで書き間違いのような面妖な字が延々と並んで奇観を呈しています。 CNS 11643はISO 2022準拠のため、EUCを構成することができます。
韓国にもJISやGB同様、ISO 2022準拠の2バイトコードの規格があります。 そのうち、JIS X 0208やGB 2312のように最もよく使われるのがKS C 5601です。 これは英数字や仮名の他、ハングル2350字、漢字(繁体字)約4000字が含まれています。
ハングルという文字は、子音字母と母音字母の組み合わせによって1文字(音節)を構成します。 具体的には、初声(子音19種)+中声(母音21種)、 または初声+中声+終声(子音27種)という構造になっていて、 計算上は19*21*(27+1)=11172字存在します。 しかし、942文字集合にはこんなにたくさん収容できませんので、 KS C 5601には、このうちよく使われるものだけが入っています。 また、漢字は読みの順に並んでいます。一部の漢字は複数の読みを持ちますが、 これらがそれぞれの読みの所に重複して収録されているのが大きな特徴です。
KS C 5601は、通常はGRに呼び出して韓国語EUCの形で使います。 メールやニュースでは7ビットでなくてはいけませんので、 ISO-2022-KRという7ビットのエンコーディング法(G1に指示してSI/SOで切り替える)で使うことになっていますが、 実際にはEUCを使っているケースが多いそうです。
ハングルの符号化法は大別して2通りあります。 1つは、前述のKS C 5601のように、 子音と母音を組み合わせてできた音節の形に対して符号を割り当てるもので、完成型といいます。 一方、ハングルの構成原理にのっとって、 1文字分のビット(通常16ビット)を3つの部分にわけ、 それぞれが初声・中声・終声を表すという方法があります。 これは組合せ型といいます。 組合せ型は、ハングルの合理的な特徴をよく生かしており、 すべての可能な組合せを表現できるため、根強い人気があります。
組合せ型コードは主にMS-DOSで使われていて、メーカーにより何種類かあるようですが、 KS C 5601-1992の付録に収録されたものは次のようになっています。 初声・中声・終声はそれぞれ5ビットで表せるので、 これに識別用の1ビットを加えて16ビット(2バイト)とします。 つまり、あるバイトのMSBが1であれば2バイトハングルコードとみなし、 次のバイトと合わせて15ビットでハングル1音節を表します。 中声の5ビットがバイト境界にまたがっていたりするので、 第2バイトにいろいろとまずいコードが現れそうな気がしますが、 これが実に巧妙にできていて、C0/C1制御文字や空白のコードは現れないようになっています。 とはいえさすがにGLの図形文字のコードと重なるのは避けられず、 そのためISO 2022にも非準拠です。
この章は、最近何かと話題のISO 10646とUnicodeの話です。
ISOでは、全世界の主要な文字を含んだ単一の文字集合ISO 10646の策定作業に着手しました。 一方、国際市場を重視し始めたアメリカの有力コンピュータ企業は、 同様の目的で、しかし10646とは全く異なるUnicode(Ver.1.0)という文字集合を策定しました。
ISO 10646は規格原案(DIS 10646 第1版)が投票にかけられましたが、 10646とUnicodeの二者並立を嫌う意見により否決されました。 そこで、Unicodeの修正案(Ver.1.1)がDIS 10646 第2版として投票にかけられ、 ISO 10646-1として成立しました。 その後、ISO 10646-1はJIS X 0221としてJIS規格にもなりました。
現在、ISO 10646-1の補遺と、それをとり入れたUnicode 2.0が発表されています。
ISO 10646はUCS(Universal Character Set, 万国文字集合)と名付けられています。 UCSは、2バイト単位の形式UCS-2と、4バイト(31ビット)単位の形式UCS-4があります。
UCS-4の4バイトの値はそれぞれ群(group)・面(plane)・区(row)・点(cell)と呼ばれます。 256の点と256の区で表される65536個のコードが1つの面を構成し、 256の面で1つの群(立方体を想像してください)を構成し、 128の群でUCS-4の全体を構成します(群のMSBは未使用)。 群00の終わりの方(群00の面E0〜FF)とUCS-4の終わりの方(群60〜7F)は 私用のために予約されています。
UCS-4の最初の面、 つまり群00の面00をBMP(Basic Multilingual Plane、基本多言語面)と呼びます。 BMPのコードを2バイトで表現したものがUCS-2であり、 Unicodeはこれとほぼ同じものです。 現在、BMP以外の面には文字は定義されていませんので、 実質的にはBMPすなわちUCS-2がすべてといっていいでしょう。
ISO 10646には、結合文字や組合せ型ハングルの使用を認めるかどうかによって、 実装水準という概念が定義されています。
- 実装水準1
- すべて使用不可
- 実装水準2
- 一部の結合文字(主にヨーロッパ諸語)と組合せ型ハングルの使用不可
- 実装水準3
- すべて使用可
Unicodeは実装水準3と規定されています。
また、UCSのすべてを実装するのは困難な場合が多いので、 その中から必要な文字だけを取り出したサブセットの使用(profiling)を認めています。
BMPは以下のように大別されます。
領域 コード範囲 内容 A(Alphabet)領域 U+0000〜U+33FF 各種文字(アルファベット、組合せ型ハングル、仮名など)・記号 U+3400〜U+4DFF Vertical Extension A(完成型ハングル移動後の空き) I(Ideograph)領域 U+4E00〜U+9FFF 漢字 O(Open)領域 U+A000〜U+ABFF 拡張用予約領域 U+AC00〜U+D7FF 完成型ハングル U+D800〜U+DFFF サロゲート・ペア R(Restricted)領域 U+E000〜U+F8FF 私用予約領域 U+F900〜U+FFFD 互換用文字など
A領域に含まれている主な文字は次の通りです。
ラテン文字、発音記号、ギリシア文字、キリル文字、アルメニア文字、 ヘブライ文字、アラビア文字、インド諸文字、タイ文字、ラオ(ラオス)文字、 グルジア文字、組合せ型ハングル、各種記号、罫線、仮名
A領域の最初の256文字(U+0000〜U+00FF)はISO 8859-1 (Latin-1)と互換になっています。 すなわち、最初の128文字(U+0000〜U+007F)はASCIIと互換になっています。
A領域には、結合文字(combining character)と呼ばれる文字が含まれています。 これは、アルファベットのアクセント記号や仮名の濁点のように、 他の文字に付加する記号類のことです。 たとえば、「ä (a-ウムラウト)」を表すには、 「a」のコードの次にウムラウトのコードを置きます。 ただし、結合文字を使うと1文字のコード長が可変になってしまって扱いにくいので、 よく使われる形については合成済み(precomposed)のコードが用意されており、 ほとんどの場合は単一のコードで表現できます。
ハングルについては、組合せ型コードが用意されています。 UCS-2の場合、1文字4バイトまたは6バイトとなります。 かつては完成型コードもありましたが、Unicode 2.0になって、 完成型ハングルは大きく再編成されてO領域に移動しました。 移動後の空き領域には、将来漢字が追加される予定です。
I領域には、中国・日本・韓国(CJK)の漢字を統合した約21000字が含まれています。 基となった主な文字集合は、中国のGB 2312、台湾のBig-5、 日本のJIS X 0208とJIS X 0212、韓国のKS C 5601です。 これら各国間では、同じ概念・起源の漢字でも、 歴史的・文化的理由により微妙に形が違っている(点画の向きや長さなど)ものが多数ありますが、 UCSではそれらを同一の文字とみなし「統合」しています。 ただし、基となった集合で区別されている文字は、 互換性のためにUCSでも区別されています。
O領域はもともとすべて拡張用予約領域でしたが、 サロゲート・ペア(後述)のための領域がとられることになり、 さらにUnicode 2.0になって完成型ハングルがA領域から引っ越してきたため、 残りはかなり少なくなりました。
R領域は特殊用途の領域であり、私用領域のほか、アラビア文字の変化形や、 既存文字集合との互換性を保つための文字などが含まれています。 例えば、シフトJISのテキストには、 カタカナや英数字を表現するのにJIS X 0201(いわゆる半角)と JIS X 0208(いわゆる全角)の2通りのコードがあります。 これをUCSに変換する際、 半角カタカナと全角カタカナを同じコードに変換してしまうと、 それをシフトJISに逆変換したとき、元のテキストと異なってしまいます。 これを避けるため、A領域の本来のカタカナとは別に、 R領域に「半角(halfwidth)カタカナ」が用意してあります。 同様に「全角(fullwidth)英数字」も用意されています。 その他、KSC 5601などで重複して収録されている漢字についても、 重複分が用意されており、可逆変換(round-trip conversion)が可能となっています。 このことからわかるように、UCSは、 既存の(単一の)文字集合/エンコーディング法との互換性に最大限の留意を払っています。
なお、ここで使用した領域という名称は、最近は使われなくなりつつあります。
既存のテキストデータの伝送路や処理系は、 ISO 2022に準拠した文字データを処理することを前提にしていますので、 そこにUCSのデータをそのまま通すと、 制御文字などと誤認されたりして問題が生じます。 そのため、UCSに適当なエンコーディングを施して安全に通すことが考えられています。 このエンコーディング法はいくつかあり、 総称してUTF (UCS Transfer Format)と呼ばれています。 これらは、UCSのASCII相当部分(U+0000〜U+007F)は通常の1バイトのASCIIに変換し、 それ以外のコードをそれぞれの方法でエンコードします。 したがって、ASCIIテキストの中にUCS(の非ASCII文字)を埋め込む方法とみることもできます。
当初ISO 10646の付録に収録されていたUTFです。 UCS-2/4の1文字を、1〜5バイトの可変長バイト列にエンコードします。 エンコード後のバイトデータは、 ISO 2022のGLおよびGR (0x21〜0x7E、0xA1〜0xFE)の範囲になっているため、 ISO 2022を前提とした伝送路を安全に通過することができます。 エンコードには除算を使います。
UTF-1は、通信や外部記憶などで用いる情報交換用エンコーディング法として設計されましたが、 UTF-8という強力な対抗馬に押され、 ほとんど使われることのないままISO 10646からも削除されてしまいました。
既存のシステムの多くは、ASCII図形文字の一部の文字を特殊文字 (区切り文字、エスケープ文字、引用符など)として使っています。 このようなシステムにはUTF-1は適しません。 UTF-1は、GLとGRの領域をフルに使っているため、 エンコード後のデータの第2バイト以降にもGLに相当するコードが現れ、 これがASCIIの特殊文字と誤認されて誤動作するおそれがあるからです (シフトJISの第2バイトに0x5Cがあるとバックスラッシュと誤認される問題と似ています)。 この点を改善したのがUTF-8です。
UTF-8は、UTF-1同様、UCS-2/4の1文字を、 1〜6バイトの可変長バイト列にエンコードします。 ただし、UCSの非ASCII文字はGR相当のコード(0xA0〜0xFF)のみを使ってエンコードします。 これにより、上記のようなシステムでも、 ASCII以外のコードがASCIIと誤認されるおそれはなくなります。また、 UTF-8はエンコード/デコードがビットシフトだけで行えるので、 効率の面でもUTF-1より有利です。
UTF-8は別名をUTF-2、あるいはUTF-FSS(File System Safe)といいます。 FSSという名前は、ファイル名に使ってもパス名の区切り文字(UNIXではスラッシュ、 Windowsではバックスラッシュ)と誤認されたりしない、 というところからきています。 UTF-8は多くの企業・組織によって支持されており、 ISO 10646の補遺に収録されてUTF-1にとってかわりました。 UnicodeをサポートするOSやアプリケーションでは、 すでに外部コードとして使われ始めています。
UTF-1やUTF-8は8ビットの伝送路を前提としていますが、 インターネットではいまだに7ビットしか通さない伝送路も珍しくありません。 また、メールのヘッダ部などでは、 ASCII図形文字の使用すら制限されていることがあります。 そのような状況でもUCSをエンコードするために考案されたのがUTF-7です。
UTF-7は、MIMEのBase64エンコーディングやuuencodeと類似の方法によって、 UCSの非ASCII文字をASCII図形文字にエンコードします。 エンコードされた非ASCII部分の前には+を、後ろには-を置くことによって、 「地」のASCIIテキストと区別します。
UTF-7はもともと上記のような制限の強い状況で使うためのものであり、 広範囲に使われることを目的としたUTF-1やUTF-8とは性格が異なります。
これは、UTFと名付けられてはいますが、 目的も内容も他のUTFとは全く異なっています。 他のUTFはASCIIテキストにUCSを混ぜるためのものですが、 UTF-16はUCS-2のテキストにUCS-4(の一部)を埋め込むためのものです。 したがって、他のUTFと併用することもできます。
UTF-16では、UCS-4のうちBMPの次の16面(群00の面01〜10、総文字数1メガ)のコードを、 O領域のコード2個(サロゲート・ペア surrogate pair)に変換してUCS-2のテキストに埋め込みます。 これにより、UCS-2で表現可能な文字数を大幅に増やすことができます。
本稿では、日本語のコード系から各種の文字集合、 ISO 2022、ISO 10646/Unicodeに至るまで、 文字コード関係の基本的な概念や規格について解説しました。 一方、本稿で取り扱わなかった話題としては、以下のようなも のがあります。
Copyright (C) 1996-1998 ITO Takayuki, All rights reserved.