文字コード判定に失敗した
つい最近作った部分で、もう判定に失敗することもないんだろうと思っていたが、
先ほど真魚で判定に失敗して文字化けさせてしまった。
そのファイルが、なぜ判定失敗したかは既にわかったので、それについての話。
とりあえず、今やってる文字コード判定のソースに書いたコメントを転載。
//実際の所この関数はどう動くのか
//lenの長さかValueの長さか、小さい方をゴールとする。
//Resultの初期値はASCIIにする。
//アルファベットなどのASCII文字しか使ってない場合は、
//どの文字コードで読み込んでも同じなんだからASCIIとなる。
//途中にUTF7だと断定出来る部分が複数あれば即終了。1個くらいは偶然あるかもなので。
//途中にJISだと断定できる部分が1カ所あれば即終了。
//途中でASCII以外の文字があればJISとUTF7の判定をやめる。
//これでJISとUTF7の判定は完璧に出来る。(たぶん)
//残り三つの判定は同時進行し、断定できた時点で即終了。
//どれとも断定できなかった場合、正当なマルチバイトの数で比較する。
//ひらがなを使ったSJISは、UTF8にもEUCにも間違えない。
//ひらがなを2文字連続で使ったUTF8は、SJISにもEUCにも間違えない。
//ひらがなを使ったEUCファイルは、SJISとして変換すると半カナが多くなるので、
//正当なマルチバイトの数を比較すればEUCだと断定できる。
//よって、ひらがなを使っている日本語ファイルなら判別は完璧。(たぶん)
//別にひらがながなくても正当なマルチバイト文字数比較で精度十分なはず。
要するに、普通の日本語ファイルでは、ひらがなを使っているのが当然であり、
2文字以上連続したひらがなを使ったファイルなら判定は完璧だろうということね。
一応、ひらがなが入ってないファイルでも十分な精度になると予想していた。
で、先ほど文字化けしたファイルは、ひらがなを含まないUTF-8のファイルだ。
小原駐車場 弘前市駅前町
って感じなんだが、正当なマルチバイトの数は、UTF-8が11、S-JISが14となった。
このファイルは、SJISとして読み込むことも出来るし、UTF-8として読み込むことも出来るし、
UTF-8だとすれば11文字分の漢字などを含むし、
S-JISだとすれば14文字分の漢字などを含んでいるから、
きっとS-JISのファイルだろうなと、内部では判断したということだった。
そりゃ、S-JISは2バイトで漢字を表すが、UTF-8では2バイト以上なので、
ひらがなを含まないUTF-8はS-JISとして判定するより文字数少なくなるさね。
こりゃぁ失敗だ。
でも、これでアイデアが浮かんだ。
正当な「マルチバイトの文字数」ではなく、「正当なマルチバイトのバイト数」にすればよかった。
それで平等な比較が出来るはずだな。