sakura icon indicating copy to clipboard operation
sakura copied to clipboard

文字コード自動判定(UTF-8をSJISと誤認)

Open tutimura opened this issue 6 years ago • 13 comments

はじめまして。 身近で文字コード判定で、少し変な挙動があったので、報告します。「こんにちわ」を表示するCプログラムで発現しました。(「こんにちは」では発現しません。)

UTF-8 で

ちわ\

というテキストファイルが、自動判定に任せると、SJISの

縺。繧十

になるという話です。

バイト列で見ると、

e3 81 a1 e3 82 8f 5c

となっていて、UTF-8 と SJIS のどちらでも正しく(!)解釈できます。

ソースコードをざっと見てみました。間違ってたらすいません。 charset/CESI.cpp の CESI::SortMBCInfo() で、nPoints の最大のエンコードを採用するようです。同点の場合には UTF-8 が優先されるはずですが、この場合には運の悪いことが起こっていました。

nPoints の計算方法を比べてみました。 UTF-8 は void CESI::GetEncodingInfo_utf8( const char* pS, const int nLen ) の num_of_utf8_encoded_bytes、SJIS は void CESI::GetEncodingInfo_sjis( const char* pS, const int nLen ) の num_of_sjis_encoded_bytes で、正しくエンコードできたバイト数を数えているようです。

ただし、7bit文字を除外して数えているので、 UTF-8 なら、末尾の \ を除いた6byte, SJIS なら、途中の半角カナを含めて7byteになり、 SJIS が採用されるという流れのようです。

文字コードの自動判定に完璧を求めるのは、そもそも無理な話だとわかっているのですが、ディフォルトのエンコードを UTF-8 にしていても SJIS に判定されるので、何とかならないかと思ったりもします。(ヒストリはクリアされているという前提です。)

判定の最初の段階で、ディフォルトエンコードでエラーなく読み取れれば、他のエンコードを調べるまでもなく、ディフォルトを採用してくれればいいような気もしていますが、ロジックが複雑になるのは好ましくないでしょうから、悩ましいですね。

tutimura avatar Sep 26 '18 04:09 tutimura