ローマ数字。ⅠやⅡ、ⅤやⅨなどのあのかっこいい数字だ。
昔々は機種依存文字として名高い文字だったが、UTF-8の時代にはそれほど困らない数字になった。
Shift-JISでも影響なく使えるので、Windowsの人もあまり困っていない。
だが昔ながらのシステムを使っている人は困っているのだ。
最近 、仕事でiconvコマンドを使ったシェルがあり、その挙動を確認中に、Windowsメモ帳で見れるのに、サクラエディタで見れないローマ数字があったので気づいた。
普通にⅠと入力してShift-JIS(Windowsなので厳密にはCP932)で保存すると、
文字コードは0x8754だった。
だが、ある方法で出力したローマ数字のⅠは
0xFA4Aだった。
2つのコードが混在
このように2つの同じローマ数字のⅠが並んでいるようなテキストがある。
文字コードはCP932だ。
それの中身を見てみると、0x8754と0xFA4Aが混ざっている。
$ hexdump -C hoge3 00000000 87 54 0a 0a fa 4a 0a |.T...J.| 00000007
普通にローマ数字をテキストエディタで書いて保存すると、0x8754が保存される。
だが、iconvコマンドで出力先文字コード(-t オプション)をIBM-943にすると、0xFA4Aになった。
二重に登録されているわけだが、0x8754の方はNEC特殊文字と言われる区画で、0xFA4AのほうはIBM拡張文字と言われる区画にある文字だそうだ。
ローマ数字について
なぜこんなことになっているのか調べてみた。
もともとShift-JISにはローマ数字は無い。
NEC特殊文字とIBM拡張文字というのが2つのベンダーが独自に拡張した区画。
wikipediaを見ると複雑な事情があったようだ。
Shift-JISの方式を利用したMS-DOSの日本語文字コードとしてCP932という管理番号を与えられて誕生した。
MS-DOSはいろんなメーカーのPCに乗せて売られていたわけで、NECのPC98やIBMのPS/55があった。
その文字集合をそれぞれのメーカーに任せてしまったので、
NECとIBMの方式がバラバラになってしまった。
Windows3.1を出すにあたりこのカオスな状況をどうにかしなくちゃいけなくなった。
そしてCP932のそれぞれの独自仕様をメーカーに任せるのをやめて、統合をした。
そしてWindows-31jという文字コードとして再出発し、CP932はWindows-31jという二つ名を持つこととなった。
というわけでWindowsで使っているShift-JISの亜種であるWindows-31j(CP932)はNEC特殊文字やIBM拡張文字が追加されている。
世間的にみんなはShift-JISはCP932の範囲を思い浮かべるかもしれないが、厳密には違い、ローマ数字や丸数字などはShift-JISには含まれていない。
iconvのIBM-943もShift-JISの拡張文字コードで、IBM拡張になっている。
IBM-932というのがあって、これが前述のCP932のIBMバージョンと同じ意味だと思われる。
そして、それを拡張してNEC特殊文字などを追加したのがIBM-943だ。
つまりこれもローマ数字が2重登録されていたわけだが
iconvコマンドで変換する時はIBMが指定した区画に優先的に変換するのだろう。
iconvでもCP932を選べばNEC特殊文字の区画の方に変換される。
ちなみにサクラエディタでは、IBM拡張文字の方の文字コードでのローマ数字は文字化けした。
なお、JIS X 0213でNEC特殊文字の区画が公式の規格になったようだ。