umq (4421) の日記

○ ◎ ●

バイト列に意味はあるのか(02)

umq による 2004年09月08日 17時38分 の日記 (#249035)

``printable'' な文字を切り出すにあたって,文字集合の話は避けて通れない。
今回は,Unicode 以前の日本語の文字集合の扱いについて,書いてみることにする。踏み込んだ解説は,色々なところに転がっているので,ここでは概要にとどめ,参考にしたサイトなりを末尾に示すことにする。

文字集合を拡張する際に,それまでの文字コードシステムとの不整合はなるべく少なくなるようにデザインする必要がある。

前回 strings(1) で扱った ``printable'' な文字は,文字コードで表すと,\x20-\x7e の 95 種類であった。これは,ASCII もしくは ISO/IEC 646 で制御文字として定義されている \x00-\x1f と,DEL として定義されている \x7f を除いた部分に相当する。この 95 文字のうち SP(\x20) は特別な意味を持つ(対応する図形を持たない)ので,これを特別扱いすることにすると,\x21-\x7e の 94 種類が,図形用文字コードとして使えることになる。

文字集合の拡張を考えた場合,これらの 94 種類の文字コードを n 個並べることで,94^n (きゅうじゅうよんのエヌ乗)個の文字を表すようにできそうだということになった。

また,同様にすると,8bit の文字集合についても,\x80-\xff の部分を,7bit の文字集合と同じように分割して,\x80-\x9f を制御文字,\xa0-\xff を図形文字に割当てると考えると,(こちらは SP や DEL がないので)\xa0-\xff の 96 種類を複数個組合わせて 96^n 個の文字を表すようにできそうである。

JIS C 6226(のちの JIS X 0208)で日本語用の文字集合を定義するにあたって,94^2 個のコードポイントを作ってそこに文字を割当てることになった。94×94 の文字コード表では行を「区(row)」と呼び,行内での位置を「点(cell)」と呼ぶ。区,点ともに1から始まる。

ワープロ専用機が出回りだした頃は,漢字変換の効率もあまりよくなく,マニュアルの末尾に,区点コード表がついていて,表から文字コードを拾って入力するというようなこともあった。

さて,図形文字として使える 94 種類の文字コードの組み合わせで文字集合を定義していること,JIS X 0208 で定義されている文字は 94×94 のサイズの区点コード表に並べられていることはわかった。
実際にアプリケーションでこれらの文字集合をどのように扱うのがよいのだろう。

従来の,いわゆる ASCII の文字は,できることならそのまま扱いたい。その上で,漢字のような 2 バイトで 1 文字を表す方法も使いたい。

方法としては,何らかの手段を講じてバイト列ごとに表す文字集合を切換えるということになる。

切換え方には,大きくわけて 2 通りあり,ひとつはバイト列の間に切り替えを示すバイト列を挟む方法,もうひとつはあるバイトの値が特定の範囲にある場合その次のバイトとセットであると取り決める方法である。前者の方法では,切り替えの対象範囲が次の切り替えバイト列までの場合と,切り替えバイト列直後の文字のみの場合がある。

実際の実装ではどうなっているかを以下におおまかに示す

  • ISO-2022-JP
    ESC(\x1b)とそれに続く数個のバイト列で切り替えを表す。この切り替え文字列を特に「エスケープシーケンス(Escape sequence)」と呼ぶ。
    エスケープシーケンスには色々なものがあるが,たとえば ESC $ B (\x1b\x24\x42)で,JIS X 0208 に対応する面に切り替え, ESC ( B (\x1b\x28\x42)で ASCII に切換える,などである。
  • EUC-JP
    ASCII の \x00-\x7f はそのまま扱う。JIS X 0208 の 2 バイト文字は第 1, 2 バイトとも \xa1-\xfe の範囲にあり,それぞれのバイト値から 160 を引けば区点コードに対応する。
    SS2(\8e), SS3(\x8f) という切り替え文字が使用できる場合がある。その場合,SS2 に続く 1 バイトが \xa1-\xfe であればそのバイトは JIS X 0201 の 8bit 面の文字(いわゆる半角カナ等)に相当するとして扱う。SS3 に続いて \xa1-\xfe が2つ続いた場合,その 2 バイトを,JIS X 0212 に含まれる文字として扱う。
  • Shift_JIS
    1 バイト文字は,そのまま扱う。2 バイト表現の文字の第 1 バイトの値は \x81-\x9f, \xe0-\xfc の範囲にある。これらは少々数が足りないので,第2バイトの範囲を少々イレギュラーにして文字を割当てている。
    そのため,区点コードと実際の文字コードとの対応関係はわかりにくい。

# 概要にしては長くなったなぁ,図示できればいいんだろうけど……

参考

[ひとつまえ]

この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。

※ただしPHPを除く -- あるAdmin

処理中...