charsets(7) プログラマの視点から見た文字セットと国際化

説明

Linux は国際化されたオペレーティングシステムである。 Linux の様々なユーティリティや、 console ドライバなどの デバイスドライバは、非ラテンアルファベットなどの マルチリンガル文字セット (multilingual character sets) をサポートしている。 これらにはラテンアルファベット文字・ギリシャ文字・ キリル文字・アラビア文字・ヘブライ文字などが含まれ、 発音区別符号 (diacritical marks)・アクセント・合字 (ligatures) なども 使うことができる。

このマニュアルページでは、プログラマの視点からみた異なる文字集合規格 (character-set standards) と、それらを Linux にどう適合させるかというこ とについて述べる。ここでは、ASCII, ISO 8859, KOI8-R, Unicode, ISO 2022, ISO 4873 の各規格について議論する。 ここでは実際にロケール文字セットとして使われている文字セットに注目し、 その他のシステムで使われている無数のものは重視しない。

glibc 2.2.3 で公式に対応しているロケールで用いられている文字セットの 完全なリストは以下の通り: ISO-8859-{1,2,3,5,6,7,8,9,13,15}, CP1251, UTF-8, EUC-{KR,JP,TW}, KOI8-{R,U}, GB2312, GB18030, GBK, BIG5, BIG5-HKSCS, TIS-620 (順不同) (ルーマニア語は ISO-8859-16 に切り替わっているかもしれない)

ASCII

ASCII (American Standard Code For Information Interchange) は 7 ビット文字集合の元となったものであり、 もともとは米語(American English) のためにデザインされた。 現在は、ECMA-6 標準の中で説明されている。

ドイツ語、フランス語、スペイン語などに 7 ビットで対応するため、 ASCII のドル記号を他の通貨記号に置き換え、 句読点を非英語文字のものに置き換えた様々な変種が存在する。 これらは全て使うべきではない。 glibc は ASCII の完全なスーパーセットでない文字セットのロケールに 対応していない。 (これらの文字セットは ISO-646 として知られる。 これは ASCII と近い関係にあり、これらの文字を置き換えることを認めている)

Linux は米国で設計されたハードウェアのために書かれたので、 はじめから ASCII をサポートしている。

ISO 8859

ISO 8859 は 15 組の一連の 8 ビット文字集合である。それらは全て 下位 (7 ビット) に US ASCII を含み、 128 から 159 には制御文字が配置され、 160 から 255 には 96 個の固定幅図形文字が配置されている。

これらのうちで、もっとも重要なのは ISO 8859-1 (Latin-1) である。これ は Linux コンソールドライバにおいてネイティブにサポートされており、 X11R6 においても同様にサポートされている。さらに、 HTML の基本文字集合である。

コンソールにおける、その他の 8859 文字集合のサポートは (setfont(8)) のようなユーザモード・ユーティリティを利用する事で可能になる。 このようなユーティリティを利用することにより、コンソールドライバにおけ るキーボードと EGA グラフィックテーブルの割り当てを変更し、 "ユーザ割り当て(user mapping)"フォントテーブルを使用することができる。

以下は、それぞれの集合の簡単な説明である。

8859-1 (Latin-1)
Latin-1 は アルバニア語(Albanian)、カタロニア語(Catalan)、デンマーク語 (Danish)、オランダ語(Dutch)、英語(English)、フェロー語(Faroese)、 フィンランド語(Finnish)、フランス語(French)、ドイツ語(German)、 ガリシア語(Galician)、アイルランド語(Irish)、アイスランド語(Icelandic)、 イタリア語(Italian)、ノルウェー語(Norwegian)、ポルトガル語(Portuguese)、 スペイン語(Spanish)、スウェーデン語(Swedish)といったほとんどの 西ヨーロッパ言語をカバーする。 ドイツ語の ij やフランス語の oe の合字、および古いスタイルの ,,ドイツ語`` 引用符はないが、許容範囲と考えられている。
8859-2 (Latin-2)
Latin-2 はスラヴ語(Slavic)、クロアチア語(Croatian)、チェコ 語(Czech)、ドイツ語(German)、ハンガリー語(Hungarian)、ポーランド語 (Polish)、ルーマニア語(Rumanian)、スロヴァキア語(Slovak)、 スロベニア語(Slovene)といった、書き文字としてラテン文字を 使用する、スラブ系言語と中央ヨーロッパの言語のほとんどをサポートする。
8859-3 (Latin-3)
Latin-3 はエスペラント(Esperanto)、ガリシア語(Galician)、マルタ語 (Maltese)などの書き手の間で良く用いられる。 (トルコ語(Turkish)はこれの代わりに 8859-9 で書かれるようになっている)
8859-4 (Latin-4)
Latin-4 はエストニア語(Estonian)、ラトビア語(Latvian)、リトアニア語 (Lithuanian)の文字を提供する。Latain-4 は、 本質的には廃止されている(obsolate である)。 8859-10 (Latin-6) と 8859-13 (Latin-7) を参照のこと。
8859-5
ブルガリア語 (Bulgarian)、ベラルーシ語 (Byelorussian)、マケドニア語 (Macedonian)、ロシア語 (Russian)、セルビア語 (Serbian)、ウクライナ語 (Ukrainian) をサポートするキリル文字集合である。 ウクライナ語では downstroke をつけた "ghe" という文字を "heh" と読み、 ghe を正しく書くには ghe に upstroke をつけなければならない。 この点については、下の KOI8-R に関する議論を参照のこと。
8859-6
アラビア語(Arabic)をサポートする。8859-6 のグリフテーブル(glyph table) は文字の形態を分割した固定幅フォントである。 そのため、適切なディスプレイエンジンが正しい initial, medial, final フォームに結合しなければならない。
8859-7
現代ギリシャ語(Modern Greek)をサポートする。
8859-8
niqud(句読点記号) のない近代ヘブライ語(Hebrew)をサポートする。 niqud と完全な聖書風ヘブライ語(Biblical Hebrew)はこの文字セットの対象外である。 Linux では、これらのためには UTF-8 が好ましいエンコーディングである。
8859-9 (Latin-5)
これは、Latin-1 の変種で、アイスランド語の文字をトルコ語(Turkish)文字に 置き換えたものである。
8859-10 (Latin-6)
Latin-6 は北欧(Nordic)地域をカバーするために Latin-4 には含まれていない イヌイット語(Inuit)(グリーンランド語(Greenlandic)) と サーメ語(Sami)(ラップ語(Lappish)) を加えてある。 RFC 1345 には、この前段階の、異なった "latin6" が載せられている。 スコルト・サーメ語(Skolt Sami)では、 さらにいくつかのアクセント記号が必要とする。
8859-11
これは拒絶された草案標準のためだけに存在する。 この草案標準は Linux でタイ語のために用いられる TIS-620 と同じものである。
8859-12
この文字セットは存在しない。 ベトナム語がこの場所を使うように提案したが、 ISO 8859 が提案する(合成でない) 96 文字に収まらなかった。 Linux ではベトナム語を扱う場合は UTF-8 が好ましい文字セットである。
8859-13 (Latin-7)
バルト海諸国の言語をサポートする。 特に、Latin-4 に存在しないラトビア語の文字を含む。
8859-14 (Latin-8)
これはケルト語の文字セットであり、ゲール語(Gaelic)とウェールズ語(Welsh)に対応する。 この文字セットは古代アイルランド語で用いられる付点付き文字も含む。
8859-15 (Latin-9)
これはユーロ記号と Latin-1 に入っていないフランス語とフィンランド語の文字が 追加されている。
8859-16 (Latin-10)
この文字セットは 8859-2 で対応する多くの言語に対応し、 さらにルーマニア語にはより完全に対応する。

KOI8-R

KOI8-R はロシアにおいて良く用いられる、ISO でない文字集合である。 下位半分は US ASCII である。上位半分は ISO 8859-5 より幾分良く デザインされたキリル文字集合である。 KOI8-U は KOI8-R を元にした共通文字セットであり、 ウクライナ語(Ukrainian) によりよく対応する。 これらのどちらも ISO-8859 シリーズのように ISO-2022 互換ではない。

Linux での KOI8-R のコンソールサポートは、 ユーザモードのユーティリティで実現されている。 これはキーボードの割り当てと EGA グラフィックテーブルを変更し、 コンソールドライバのフォントテーブルに "ユーザ割り当て" を行う。

JIS X 0208

JIS X 0208 は日本語の国定標準文字セットである。 他にもいくつか日本語の国定標準文字セットはある (JIS X 0201, JIS X 0212, JIS X 0213 など)が、これが最も重要である。 文字は 94x94 の 2 バイトマトリックスに配置される。 各バイトは 0x21-0x7e の値を持つ。 JIS X 0208 は文字セットであり、エンコーディングではないことに注意すること。 これは、 JIS X 0208 自身はテキストデータの表現には使われない、ということである。 JIS X 0208 は、 EUC-JP, Shift_JIS, ISO-2022-JP といったエンコーディングを 構成する部品として用いられる。 EUC-JP が Linux において最も重要なエンコーディングであり、 US ASCII と JIS X 0208 を含んでいる。 EUC-JP では、JIS X 0208 文字は 2 バイトで表現され、 各バイトは JIS X 0208 コードに 0x80 を加えたものである。

KS X 1001

KS X 1001 は韓国の国定標準文字セットである。 JIS X 0208 と同様に、文字は 94x94 の 2 バイトマトリックスに配置される。 KS X 1001 は JIS X 0208 と同様に、 EUC-KR, Johab, ISO-2022-KR といったエンコーディングの部品として用いられる。 EUC-KR は Linux において最も重要なエンコーディングであり、 US ASCII と KS X 1001 を含んでいる。 KS C 5601 は KS X 1001 の古い名前である。

GB 2312

GB 2312 は、簡体文字を表現するための中国の国定標準文字セットである。 JIS X 0208 と同様に、文字は 94x94 の 2 バイトマトリックスに配置され、 EUC-CN に用いられる。 EUC-CN は Linux において最も重要なエンコーディングであり、 US ASCII と GB 2312 を含んでいる。 EUC-CN はしばしば GB, GB 2312, CN-GN などと呼ばれる。

Big5

Big5 は台湾で繁体文字を記述するのに一般的に使われる文字セットである。 (Big5 は文字セットとエンコーディングの両方である。) これは US ASCII の上位集合である。 非 ASCII 文字は 2 バイトで表現する。 0xa1-0xfe のバイトは 2 バイト文字の 1 文字目として用いる。 Big5 とその拡張は台湾と香港で広く用いられている。 これは ISO 2022 準拠ではない。

TIS 620

TIS 620 はタイの国定標準文字セットで、US ASCII の上位集合である。 ISO 8859 シリーズと同様に、タイ文字は 0xa1-0xfe に配置される。 TIS 620 は Linux でのみ一般的に用いられている文字セットであり、 また、UTF-8 は合成文字も持っている。

UNICODE

Unicode (ISO10646) は、人間が用いる全ての言語の全ての文字を、 明確にあらわすことを目的とした規格である。 Unicode の構造は各文字のエンコードに 20.1 ビットを与えている。 ほとんどのコンピューターは 20.1 ビットの整数を扱えないので、 Unicode は普通内部データとして 32 ビット整数にエンコードされ、 16 ビット整数の列 (UTF-16)(ある種の珍しい文字をエンコードする場合にだけ 2 つの 16 ビット整数が必要となる)か、 8 ビットバイトの列 (UTF-8)として扱われる。 Unicode についての情報は、 から得られる。

Linux は 8-bit Unicode Transformation Form(UTF-8) を用いて Unicode を あらわす。 UTF-8 は Unicode の可変長表現である。UTF-8 は 7 ビットを 符号化するのに 1 バイトを、 11 ビットでは 2 バイトを、 16 ビットでは 3 バイトを、 21 ビットでは 4 バイトを、 26 ビットでは 5 バイトを、 31 ビットでは 6 バイトを用いる。

0,1,x をゼロ、1、任意のビットとすると、あるバイト 0xxxxxxx は Unicode では 00000000 0xxxxxxx とあらわされる。これは、ASCII の 0xxxxxxx と同じ シンボルのコードである。このように、ASCII は変更なしに UTF-8 に変換でき、 ASCII のみを使う場合は、コードにおいてもファイルサイズにおいても、 変更に関して何も気にしなくてよい。

110xxxxx というバイトは 2 バイトコードの始まりである、そして、110xxxxx 10yyyyyy は 00000xxx xxyyyyyy というように組み立てられる。また、 1110xxxx は 3 バイトコードの始まりであり、1110xxxx 10yyyyyy 10zzzzzz は xxxxyyyy yyzzzzzz というように組み立てられる(UTF-8 が 31 ビット ISO 10646 コードを利用するときは、この工程は 6 バイトコードまで発展させられる)。

ISO-8859-1 文字セットを使うほとんどのユーザにとって、 この事実は、ASCII の範囲外を使った文字は 二つのバイトに符号化されるということを意味する。このことから (UTF-8 を使うと、ISO-8859-1を使用している)元々のテキストファイルの サイズから 1 〜 2 パーセント大きくなってしまうことになる。 ロシア語やギリシャ語を利用するユーザーにとっては、 これによって元のテキストは 2 倍の大きさになることになる。 なぜならこれらの言語はほとんどが ASCII の範囲外だからである。 現在 16-bit コードを広く利用している日本語を利用するユーザには 3 バイト必要となる。 Unicode への変換にアルゴリズム的変換をすればよい文字セットがある (特に ISO-8859-1)一方、一般的には変換テーブルが必要であり、 16 ビットコードの場合はこのテーブルはかなり大きなものとなる。

UTF-8 は自己同期的である。10xxxxxx は終端であり、ほかのバイトはコードの 先頭である。UTF-8 の文字列における ASCII のバイトは、常にその文字自身を 表現することに注目してほしい。特に、幾つかの大きなコードのパートを形成 するために、NUL ('\0') や '/' を埋め込む必要はない。

ASCII と NUL と '/' は変更されないため、カーネルは UTF-8 を 使用していることを特に意識しなくても良い。 カーネルはバイトが何をあらわしているかに注意する必要がない。

Unicode データ列のレンダリングは典型的には Unicode のサブセットから グリフへのマップである"サブフォント(subfont)"テーブルを利用して 行われる。カーネル内部では、Unicode を ビデオ RAM 内部にロードされた サブフォントとして記述する。これは、UTF-8 モードでは 512 の異なったシンボルを 持った文字集合を利用可能であることを意味する。 これは、日本語、中国語、韓国語では十分ではない、しかし、その他の利用では 十分である。

現在のところ、コンソールドライバは合成文字を扱えない。 従って、タイ語、スー語やその他の合成文字が必要な文章は コンソールでは扱えない。

ISO 2022 and ISO 4873

ISO 2022 と ISO 4873 標準では、 VT100 の動作に基づいたフォントコントロールモデルを述べられている。 このモデルは Linux カーネルや xterm(1) において(部分的に)サポートされている。 この標準は日本や韓国においてよく用いられる。

G0, G1, G2, G3 と呼ばれる 4 つの図形文字集合がある。 これらのうちのひとつは、最上位ビットが 0 であるコードのための現在の文字集合 (初期値は G0)、またひとつは最上位ビットが 1 であるコードのための現在の 文字集合(初期値は G1)である。それぞれの図形文字集合は 94 か 96 の文 字を持ち、基本的に 7-bitの文字集合であり、040-0177 (041-0176) か 0240-0377 (0241-0376)のコードを使う。 G0 は常に 94 文字で 041-0176 のコードを使用する。

文字集合の切り替えはシフトファンクション ^N (SO または LS1), ^O (SI または LS0), ESC n (LS2), ESC o (LS3), ESC N (SS2), ESC O (SS3), ESC ~ (LS1R), ESC } (LS2R), ESC | (LS3R) を使って行われる。 ファンクション LSn は最上位ビットが 0 であるコードのための文字集合を Gn に設定する。 ファンクション LSnR は最上位ビットが 1 であるコードのための文字セットを Gn に設定する。 ファンクション SSn は(最上位ビットの値にかかわらず)次の文字のみ 文字集合を Gn (n=2 または 3)に設定する。

94 文字集合では、エスケープシーケンス ESC ( xx (G0 用), ESC ) xx (G1 用), ESC * xx (G2 用), ESC + xx (G3 用) によって、Gn 文字集合 を用いるように指示される。 xx は "ISO 2375 International Register of Coded Character Sets" で 決められている一文字、または二文字である。 たとえば ESC ( @ は ISO 646 文字集合を G0 として選び、ESC ( A は(ナンバーサイン(#)の代わりに、ポンド(£)を持つ) UK スタンダード文字集合を 選択する。ESC ( B は(通貨記号のかわりにダラー($)を持つ) ASCIIを選択する。 ESC ( M は アフリカ言語(African languages) を選択し、ESC ( ! A は キューバ語(Cuban)文字集合を選択する。などなど…

96-文字集合では、エスケープシーケンス ESC - xx (G1 用), ESC . xx (G2 用), ECS / xx (G3 用)を用いることで、 Gn 文字集合を使用するように指示される。 例えば、ESC - G はヘブライアルファベット(Hebrew alphabet) を G1 として選択する。

マルチバイト文字集合ではエスケープシーケンス E $ xx または ESC $ ( xx (G0 用), ESC $ ) xx (G1 用), ESC $ * xx (G2 用), ESC$ + xx (G3 用) を 用いることで、 Gn 文字集合を使用するように指示される。 例えば、ESC $ ( C は 韓国語(Korean)文字集合を G0 として選択する。 ESC $ B によって選択される日本語文字セットは、より最近のバージョンでは ESC & @ ESC $ B によって選択されるようになった。

ISO 4873 はより制限された文字集合の利用を規定する、その規定で は、G0 は(常に ASCIIに)固定される。従って、G1, G2, G3 は最上位ビットが セットされたコードとしてのみ呼び出すことができる。 特に、^N^O は用いられず、ESC ( xx は xx=B としてのみ 用いることができ、 ESC ) xx, ESC * xx, ESC + xx はそれぞれ ESC - xx, ESC . xx, ESC / xx と 等価になる。

この文書について

この man ページは Linux man-pages プロジェクトのリリース 3.65 の一部 である。プロジェクトの説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。