おはようございます、川合です。
gccの移植をやってて思うのですが、なにやらいろんな文字コード(
厳密にはエンコード)に対応するためにややこしいことをやっています
。根が単純な僕の脳みそでは理解しにくく、ここはいじって簡単にして
みようと思いました。・・・簡単にするかどうかはまだ決めていません
が、もし簡単にするとしたらどうしたらいいかをここで書きたいと思い
ます。
世の中にはいろんなエンコード方式がありますが、まずはそれらをじ
っくり見てみようと思いました。とはいっても、僕が把握しているのは
ごくわずかです(日本語EUC、韓国語EUC、日本語シフトJIS、ISO 2022
、UTF-8、単純32bitエンコード)。
なお、UTF-8については、以下のページで勉強しました。
http://www.asahi-net.or.jp/~dp8t-asm/java/tips/UTF8.html
単純32bitエンコードというのは、僕が好きなやつで、ようするにcha
rを32bitにしてしまえ的な発想です。'A'のコードは8bitの0x41ではな
く、32bitの0x00000041になるわけです。
---
さてエントリーした6つのエンコード方式について次の3つの観点から
比較してみます。
・ファイルシステムセーフ性
ファイルシステムセーフというのは、さっき知った言葉なのですが、
文字コードの第二バイト以降にバックスラッシュのコードが入ったりし
ないということです。ここではこの意味をもっと拡張して、エンコード
した文章を8bitずつ区切ってアクセスした場合、不用意に0x00〜0x7fの
コードが出現しない、という風に解釈することにします。
この観点では、シフトJISと単純32bitエンコードがアウトです。まあ
シフトJISがアウトなのは残念でもなんでもないんですが(僕はI.Tak.さ
んと同じく、シフトJISが大嫌いです)、単純32bitエンコードがアウト
なのは残念です。というか、これが単純32ビットエンコードの唯一の欠
点でもあります。
ISO 2022については、GLをASCII固定にすればOKです。GRにのみ呼び出
して運用するわけです。
・エンコード可能な文字数
日本語EUC : 128 + 94 * 94 + 94 + 94 * 94 = 17894
(ASCII + 漢字 + 半角カナ + 補助漢字)
韓国語EUC : G2とG3をどう拡張していくかによります。
日本語シフトJIS : 128 + 63 + 63 * 190 = 12161
(0xa0、0xfd、0xfeもフルに使うとして計算)
ISO 2022 : エスケープシーケンスでいくらでも拡張可能
UTF-8 : 128 + 2048 + 65536 = 67712
(とりあえずややこしいサロゲートを使わないと仮定)
単純32bit : 2^32 = 4294967296
僕の考えでは、サポート文字数が最低で100万くらいはないと将来性
に問題ありだと思っています。だから、日本語シフトJIS、日本語EUC、
サロゲートなしのUTF-8はアウトです。
・文字化け耐性
これはエンコードされた文字列(ここではテキストファイルもやたら
と長い一つの文字列と解釈します)の任意のビットを反転させたとき、
最大で何文字文字化けしてしまうかを考えます。ベストは、1文字しか
化けないことです。2文字以上化けたらアウトとします。なお0x4dが0xd
になってしまったりすると表示内容が大きく変わることになりますが、
ここでは制御文字はそういうカーソル移動をしない通常の文字として表
示する上での文字化けを論じるとします。
日本語EUC : アウト(例:e1 9e e1 9e e1 9eの最初の1バイト目が61
になったら、連鎖して全ての文字が文字化けする)
韓国語EUC : アウト(日本語EUCと同じ理由)
日本語シフトJIS : アウト(日本語EUCと同じ例)
ISO 2022 : アウト(EUCのスーパーセットなんだから当然)
UTF-8 : セーフ
単純32bit : もちろんセーフ
---
ということで、僕はUTF-8が結構気に入りました。特にgccの移植とい
うことを念頭に考えると、ファイルシステムセーフ性を無視するわけに
は行きません。また僕は文字化け耐性も重要な要素だと勝手に思ってい
るので、ISO 2022系(EUC含む)は好きじゃないです。・・・シフトJIS
なんて論外です。
しかしUTF-8がベストかというと、そうでもありません。ややこしい
サロゲートを扱わないとするとたったの7万字弱しか扱えません。とい
うことで、即席で新しいエンコード方法を考えてみました。「単純川
合エンコード(仮称)」略してSKEとでもしましょうか。
0x00〜0x7f : ASCIIを表わす
0x80〜0x9f, 0xff : この辺を使うとファイルシステムセーフ性に問
題があるかもしれないので、とりあえず利用しないことにする
(UTF-8では使っているので大丈夫なのかもしれませんがね)
0xa0〜0xdf : 2バイト目以降のコード(6bitの自由度)
0xe0〜0xe1 : 将来の拡張のためにリザーブ
0xe2〜0xef : 複数バイトコードの先頭(下位4bitが後続するバイト
数を意味する)
0xf0〜0xfe : 将来の拡張のためにリザーブ
たとえば12bitの0x0123というコードは、「e2 a4 c3」の3バイトにな
ります。18bitまでなら「e3 ?? ?? ??」の4バイトです。24bitなら5バ
イトコードです(僕としてはこのレベルでとりあえず満足です)。また
僕の予期しない拡張が必要になったとしても、空きは十分です。最大の
15バイトを使った場合、90bitもの文字コードに対応できます。そして
ルールはサロゲートを使わないUTF-8よりもさらに単純といえるでしょ
う。13bit以上(漢字はこれに該当すると思われる)だと、容赦なく4バ
イトになってしまうのが残念ですが(UTF-8だと16bitまでなら3バイト
に収まる)、単純性と拡張性に免じて許してください。僕としては、サ
イズが33%アップする代わりに処理が単純になって大きな拡張性が保証
されるので、UTF-8よりもSKEの方がずっといいと思います。サイズがほ
しいなら圧縮すればいいんですし、もっと単純にしたければ単純32bit
へ行くしかないでしょう。SKEはそのバランスが良いと思います。
gccの移植に当たっては、SKEに特化して移植するつもりはありません
が、SKEでもすんなり通るようにしたいです。シフトJISには配慮しない
ことにします。行末のバックスラッシュに対応するのが面倒なので。同
じ理由で、僕の好きな単純32bitもとりあえずパスです(将来はサポー
トするかもしれませんが)。OSASKでシフトJISで書かれたコードをコン
パイルするときは、nkfなどでコンバートしてからコンパイルしましょ
う。シフトJISが重要な場合は移植していない普通のgccを使ってもらう
というのを現在の方針とします。introシリーズもOSASK上でコンパイル
できるようになったら、順次EUCかSKEにしていきます(SKEにする場合
、teditcも対応させます)。
---
こういうことは早めに書いてI.Tak.さんの意見を伺おうと思ったので
予定外でしたが早めに書きました。ご意見などがありましたら、I.Tak.
さんに限らず、なんでもどうぞ。
それでは。
--
川合 秀実(KAWAI Hidemi)
OSASK計画代表 / システム設計開発担当
E-mail:kawai !Atmark! imasy.org
Homepage http://www.imasy.org/~kawai/