ファイルに Unicode (1 文字あたり 16 バイト) または 8 ビット ASCII コンテンツがあるかどうかを知ることは可能ですか?
8 に答える
ファイルにこれが存在する場合は、バイト順マークを読み取ることができる場合があります。
UTF-16 文字はすべて 16 ビット以上であり、一部は正しいプレフィックス (0xE000 から 0xFFFF) を持つ 32 ビットです。したがって、単純に各文字をスキャンして、128 未満では機能しないかどうかを確認します。たとえば、2 バイト 0x20 0x20 は、ASCII と UTF-8 で 2 つのスペースをエンコードしますが、1 文字 0x2020 (ダガー) を UTF-16 でエンコードします。テキストが時折非 ASCII 文字を含む英語であることがわかっている場合、ほとんどすべてのバイトはゼロになります。しかし、テキストやそのエンコーディングに関するアプリオリな知識がなければ、一般的な ASCII 文字列と一般的な UTF-16 文字列を区別する信頼できる方法はありません。
Brian Agnewが、ファイルの先頭に表示される可能性のある特別な 2 バイトであるbyte order markの読み取りについて述べたことと同じです。
また、ファイル内のすべてのバイトをスキャンし、それらがすべて 128 未満かどうかを確認することで、それが ASCII であるかどうかを知ることもできます。それらがすべて 128 未満である場合、それは単なる ASCII ファイルです。それらのいくつかが 128 を超えている場合、そこには別のエンコーディングがあります。
まず、ASCII は 7 ビットであるため、いずれかのバイトに上位ビットが設定されている場合、ファイルが ASCII ではないことがわかります。
ISO-8859-x、Windows-1252 などのさまざまな「一般的な」文字セットは 8 ビットであるため、1 バイトおきに 0 の場合は、ISO-8859 のみを使用する Unicode を扱っていることがわかります。文字。
Unicode と UTF-8 などのエンコーディングを区別しようとすると、問題が発生します。この場合、ほぼすべてのバイトに値があるため、簡単に判断することはできません。Pascal が言うように、コンテンツのある種の統計分析を行うことができます。アラビア語と古代ギリシャ語は、おそらく同じファイルには含まれないでしょう。ただし、これはおそらく価値がある以上の作業です。
OPのコメントに応じて編集:
コンテンツ内に値が 0 のバイト (ASCII NUL) が存在するかどうかを確認し、それに基づいて選択するだけで十分だと思います。その理由は、JavaScript キーワードが ASCII であり、ASCII が Unicode のサブセットであるためです。したがって、これらのキーワードの Unicode 表現は、ASCII 文字 (下位バイト) を含む 1 バイトと、0 (上位バイト) を含む別のバイトで構成されます。
注意すべき点は、ドキュメントを注意深く読んで、「Unicode」という言葉の使用が正しいことを確認することです (関数を理解するためにこのページを見ましたが、それ以上は調べませんでした)。
この問題を解決する必要のあるファイルが毎回十分に長く、それが何であるかがわかっている場合(たとえば、Unicodeの英語テキストまたはASCIIの英語テキスト)、簡単な頻度分析を行うことができます。 charsを使用して、分布がASCIIまたはUnicodeのように見えるかどうかを確認します。
Unicode はアルファベットであり、エンコーディングではありません。あなたはおそらくUTF-16を意味していました。テキストのエンコーディングを自動検出するライブラリはたくさんありますが (python-chardet がすぐに思い浮かびます)、それらはすべてヒューリスティックを使用します。
特定のユースケースでは、簡単にわかります。ファイルをスキャンするだけで、NULL( "\ 0")が見つかった場合は、UTF-16である必要があります。JavaScriptにはASCII文字が必要であり、UTF-16では先頭の0で表されます。