半角カタカナと全角ひらがなの文字コード

今日お会いした方から、W45TからiPhoneへの電話帳データ移行 - すぎゃーんメモに対してのツッコミをいただいた。
モジュールを使った変換を使いまくっていたのが印象的だったそうで。
半角カタカナから全角ひらがなの変換くらいなら、わざわざモジュールを使わなくてもできるんじゃないか、というお話になったので調べてみた。


今回扱ったものはShift-JISで半角カタカナになっているものを全角ひらがなに直そうとしたもの。
W45TからiPhoneへの電話帳データ移行 - すぎゃーんメモでは、Encode::JP::H2Zというモジュールを使用して変換した。
これを使わずに変換を行うことができるのだろうか?
ということでバイナリを覗いてみる。

あいうえお
アイウエオ

というShift-JISのテキストファイルをhexdumpでみてみると、

$ hexdump hoge.txt
0000000 82 a0 82 a2 82 a4 82 a6 82 a8 0a b1 b2 b3 b4 b5
0000010 0a

という内容だった。
全角ひらがなの部分は2バイト、半角カタカナの部分は1バイトになるらしい。
下記リンクにコード表が載っていた。
ƒR[ƒh•\@ƒ@³‹K•\Œ»@ƒ@GŠÛ‚¿‚܁`‚é
ここに書いてある通り、このShift-JISの半角カタカナは

b1 ア
b2 イ
b3 ウ
b4 エ
b5 オ

という順番になっているのに対し、全角ひらがなは以下のような順番になっている。

区 点 JIS  SJIS EUC  UTF-8  UTF-16 字
04 01 2421 829F A4A1 E38181 3041   ぁ
04 02 2422 82A0 A4A2 E38182 3042   あ
04 03 2423 82A1 A4A3 E38183 3043   ぃ
04 04 2424 82A2 A4A4 E38184 3044   い
04 05 2425 82A3 A4A5 E38185 3045   ぅ
04 06 2426 82A4 A4A6 E38186 3046   う
04 07 2427 82A5 A4A7 E38187 3047   ぇ
04 08 2428 82A6 A4A8 E38188 3048   え
04 09 2429 82A7 A4A9 E38189 3049   ぉ
04 10 242A 82A8 A4AA E3818A 304A   お

参考:Unicode対応 文字コード表
小文字が入ったりすることで順番が続かない…!その他にも濁点や半濁点を持つ文字などもあり、明らかに半角カタカナのものとは並び順がちがうので、正規表現などによる単純な置換やオフセットでは変換できそうにない。それぞれの半角カタカナ文字に対応する全角ひらがな文字のコード変換テーブルを自前で用意でもしない限りは。。。
で、実際にEncode::JP::H2Zのソースを"perldoc -m Encode::JP::H2Z"で覗いてみると…
しっかり変換テーブルがずらーっと書いてあるw
ただし用意されているのはEUC-JPの半角カタカナから全角ひらがなに変換するものだけっぽいので、やはり一度Shift-JISからEUC-JPに変換して、それを使って半角カタカナ→全角ひらがなの変換をする必要があるみたい。
なんにせよ、自前で変換テーブルを用意する手間を考えると、今回のような場合はEncode::JP::H2Zモジュールを使うという選択は正しいかな、と思いました。


とは言え、全角カタカナから全角ひらがなへの変換やその他の操作についてはもっとキレイにやる方法があったかも知れませんが orz
それこそ全角カタカナ→全角ひらがなの変換なんて正規表現でできると思ったんですが…なぜかウマく動かなかったのでモジュールを使ってしまいました。このへんについてはもうちょっと調べてみます。


文字コードとかよく分かってない素人なのでツッコミがあればお願いします ><