"BOKU"のITな日常

還暦越えの文系システムエンジニアの”BOKU”は新しいことが大好きです。

文字コードで悩まされるなんて久しぶり/JIS7(ISO-2022-JP)とJIS8の話

ユニコードUTF-8)に統一された環境で楽をしているおかげで忘れかけていた「文字コードの煩わしさ」に久々にどっぷりハマった経験をしたので、書いておきます。

f:id:arakan_no_boku:20191002201759p:plain

 

JISコードの固定長ファイルと聞いてました

 

きっかけは、ごく軽い依頼でした。

文字コード「JISの固定長データ」をPCに取り込みたいんだというだけの話です。

最近、UTF-8以外の文字コードを扱うことが、ほとんどないので「今時??」とは思いましたが、まあいいやと引き受けましてサクッと作ってみたのですが・・・。

これが、はまりました(笑)。

データ長が指定より長い・・というエラーがでまくるのです。

データをエディタで開いて見直しても、問題はありません。

指定の桁(文字)数に収まってます。

ところがプログラムで読み込むと指定の桁より6文字分長いと怒られる。

デバッグしてみると・・。

確かに、文字数チェックのところで6文字多い文字数でカウントされてます。

どういうことかと悩みました。

 

16進ダンプをとってみたらわかりました

 

エディタではわからないので、デバッグ出力を16進ダンプしてみました。

すると、元データの「半角カナ」文字があるあたりが怪しい。

例えばこんな感じでした。

1B 28 49 3B 38 57 32 39 5D 3C 5E 1B 28 42

この黒文字部分の「 3B 38 57 32 39 5D 3C 5E」が、半角カナ文字です。

その前後の赤文字部分「1B 28 49」と「1B 28 42」は、元のテキストには対応する文字がありません。

間違いなく、この6文字が犯人です。

でも・・うーーん。

この数字の並び・・どっかで見たことあるんですよね。

結局。

5分ほど眺めて・・思い出したわけです。

これは「エスケープシーケンスコード」だと。

x0213.org

 何のことはない。

入力データが壊れていたのです。

後でわかったのですが、依頼した人が、「JISの固定長データ」をPCのJISで保存したら壊れるのを知らず、エディタで中身を確認した時に、同じエンコード「JIS」だから大丈夫だと思って、渡す前に上書き保存してしまったみたいなのですね。

でも・・。

正直、なんで「JISの固定長」のデータを「JIS」で保存して、データが壊れるのか?というのを説明するのが、また、ややこしかったのですが。

 

JISには大きくわけると2種類あるのです

 

そもそも。

JISと呼ばれるものは大きく2つにわかれます。

ISO-2022-JP(JIS7)系とJIS8系です。

一番大きな違いは、ISO-2022-JP(JIS7)には、シフトイン、シフトアウトの考え方があることです。

www.ohsumap.jp

簡単に整理すると。

まず、「ISO-2022-JP」というのは、JIS7をベースに電子メールなどに使うために決められたものです。

JIS7の最大の特徴は、英大文字・小文字と半角カナのコードが重複していることです。

JIS7のエリアは元々半角カナなんて考慮せずに決められていたので足らないからです。

なので。

重複していても処理できるように、「ここからは半角カナとして使う」とか「ここからは英字として使う」という宣言によって、切り替えをするわけです。

その切替を示すコードのことを「シフトイン」「シフトアウト」と言います。

上記で「エスケープシーケンス」と書いたのも、それにあたります。

問題は・・ですね。

Windowsのエディタや文字コード変換ツールなどでJISを指定すると、この「ISO-2022-JP」が適用されるということです。

charset.7jp.net

さて。

ISO-2022-JPのそのへんの仕様は以下のように説明されてます。

ASCIIと漢字のコード範囲が重複するため、エスケープシーケンスによって切り替えます。

ESC $ @ 漢字の開始(旧JIS漢字 JIS C 6226-1978)

ESC $ B 漢字の開始 (新JIS漢字 JIS X 0208-1983)

ESC & @ ESC $ B 漢字の開始 (JIS X 0208-1990)

ESC ( B ASCIIの開始ESC ( J JISローマ字の開始

ESC ( I 半角カタカナの開始

この「半角カタカナの開始<ESC ( I>」は16進数だと「1B 28 49」です。

そして「ASCIIの開始<ESC ( B>」は「1B 28 42」です。

これでつながります。

つまり。

JISだから大丈夫と思って保存した際に、裏では「JIS(ISO-2022-JP)」に変換されて半角カナエリアの開始終了にエスケープシーケンスコードが6文字分セットされていたというわけなのです。

 

JIS8の半角英数カナはSJISと同じなんだな

 

じゃあ、JIS8ってなんなのよ・・ということですが。

JIS8は半角カナにもちゃんとコードが割り当てて、シフトイン・シフトアウトのコードを挟まなくてもよくしたものと考えるとわかりやすいです。

固定長というのは、先頭から何文字目から何ケタ分・・みたいに意味付けをしますので、シフトイン・シフトアウトみたいな余分なものがはいってくると非常に具合がわるいわけですね。

とにかく。

JIS8なら余分なシフトイン・アウトコードが入らないので、固定長の桁を保証できる・・というのが重要なところで、だから、「JISの固定長」・・というのは、暗黙的に「JIS8の固定長」なのです。

今時、こんなこと知ってるのは、汎用機経験のある「高齢者」だけかもしれないなあ・・と思ったりもしますけどね。

 

JIS8はSJISの1バイトコード部分と考えればいいんです

 

実は。

JIS8の「半角英数字」・「半角スペース」・「半角カナ」のコードはSJISと同じです。charset.7jp.net

 

www.asahi-net.or.jp

だから。

JIS8の固定長は普通に「SHIFT-JIS(SJIS)」で読めばよいわけです。

気づけば簡単なことなので、なんとかなりました。

でも。

やっぱり文字コードがからむとややこしいですね。

昔、汎用機全盛時は「EBICDIC」とか「JIS7」「JIS8」「EUC」「SJIS」などなど、常に文字コードを意識しながら仕事してたな・・と久々に思い出し、ユニコードがある現代は、ほんと良い時代だな。

そう思ったのです。

今回はこんなところで。

ではでは。