Google Adsense

文字コードの判定

.NET Framework ではエンコーディングを指定してテキストファイルを読み込むことはできますが、 読み込もうとするテキストファイルがどのエンコーディングで作成されているかを知ることができないようです。

そのために、自分なりに文字コードを判定することを考えてみました。 ここでの目標は ASCII, iso-2022-jp, shift_jis, euc-jp 及び UTF-8 の各文字コードを判定することです。

※記述に誤りがあることに気がついた場合は、その内容を 「文字コードの判定(補足)」 に記述しますのであわせて御覧になってください。

※このページの作成に当たっては、 「文字コードの話」、 「日本語と文字コード」、 「漢字コードについて」、 「ISO-2022-JP - Wikipedia」、 「文字コードの部屋 -- 文字セットの種類」、 「Tip’s - 日本語文字コードの認識 - ■G-PROJECT■」、 「文字コードを判別する: .NET Tips: C#, VB.NET, Visual Studio 」 他多数のサイトを参考にさせて頂きました。ここに御礼を申し上げます。

※ 2008/02/22 追記 : 参考にさせて頂いた「Tip’s - 日本語文字コードの認識 - ■G-PROJECT■」へのリンクは
現在、「G-PROJECT」のトップページへ行くようです。 (サイト全体にわたるリニュアルが頻繁に行われているもようです ... )

※2008/03/20 追記:
現在は、「UTF-16」および「UTF-32」を含めて自動判別して表示するテキストビューアとして 「SoftWare」 のページで実行可能ファイルとソースファイルを公開していますので よろしければ合わせて御覧ください。 (.NET Framework 2.0 or later で動作します)

.NET Framework での 日本語文字コードの エンコーディング 一覧

次の表は、.NET Framework クラス ライブラリ の System.Text.Encoding クラス で サポートされている
日本語文字コードの エンコーディング の一覧を示しています。

日本語文字コードの エンコーディング
コード ページ 名前 表示名
932 shift_jis 日本語 (シフト JIS)
10001 x-mac-japanese 日本語 (Mac)
20290 IBM290 IBM EBCDIC (日本語カタカナ)
20932 EUC-JP 日本語 (JIS 0208-1990 および 0212-1990)
50220 iso-2022-jp 日本語 (JIS) *
50221 csISO2022JP 日本語 (JIS 1 バイト カタカナ可) *
50222 iso-2022-jp 日本語 (JIS 1 バイト カタカナ可 - SO/SI) *
51932 euc-jp 日本語 (EUC) *

※最後の列にアスタリスク (*) が付いているコード ページは、基になるプラットフォームに関係なく、
.NET Framework でネイティブにサポートされています。

※以降では ASCII と上の表の iso-2022-jp, shift_jis, euc-jp 及び UTF-8 について記述 ( メモ書き程度ですが... ) してみたいと思います。

ASCII ( American Standard Code for Information Interchange )

ASCII は 0x00~0x7F の 7 ビットの文字コードであり、その構成は次のようになっています。

コード体系
コード範囲(16進) 内容
0x00~0x1F 制御文字(control characters)
0x20 空白(SP)
0x21~0x7E 図形文字(graphic characters)
0x7F 制御文字DEL(delete)

※他の文字コードと重なっていますので注意が必要です。 ( 特に ISO-2022-JP に注意! )

iso-2022-jp : 日本語 (JIS)

JIS コード には 8 ビットJIS もあるようですが、ここでは 7 ビットのコードである ISO-2022-JP を扱います。

ISO-2022-JP は 0x00~0x7F の 7 ビットの文字コードであり、その構成は次のようになっています。

コード体系
コード範囲(16進) 内容
0x00~0x1F、0x7F 制御コード
0x20~0x7E ASCII文字
0x21~0x5F 半角カタカナ
0x2121~0x7E7E 漢字 ( 第1バイト・第2バイトとも 0x21~0x7E )
0x2121~0x7E7E 補助漢字 ( 第1バイト・第2バイトとも 0x21~0x7E )

上の表で分かるように、 ASCII文字 と 半角カタカナ, 漢字, 補助漢字 のコード範囲が重複するため、
通常は次のような エスケープシーケンス によって切り替えます。

ISO-2022-JP で通常使われる エスケープシーケンス
記号表記 16進表記 意味
ESC ( B 1B 28 42 ASCII
ESC ( J 1B 28 4A JIS X 0201-1976 Roman Set
ESC ( I 1B 28 49 JIS X 0201-1976 片仮名
ESC $ @ 1B 24 40 JIS X 0208-1978(通称:旧JIS)
ESC $ B 1B 24 42 JIS X 0208-1983(通称:新JIS)
ESC & @ ESC $ B 1B 26 40 1B 24 42 JIS X 0208-1990
ESC $ ( D 1B 24 28 44 JIS X 0212-1990(JIS補助漢字)

※ ASCII のコードと完全に重なっていますので注意が必要です。

※文字列中に上の表の エスケープシーケンス の パターン が現れたら文字コードは ISO-2022-JP だと考えられます。

※「ISO-2022-JPとは 【JISコード】 - 意味・解説 : IT用語辞典」 等を参照すると、「JIS X 0208:1997」も対象にすべきなのかと思いましたが、 「ISO-2022-JP - Wikipedia」、 「ISO/IEC 2022#ISO-2022-JP - Wikipedia」等を参照すると、
 JIS X 0208:1997では、附属書2「RFC1468符号化表現」として ISO-2022-JP をJISの規定としたが、この符号化表現が「ISO/IEC 2022に適合するものではない」[12]と付記している。
との表現がありましたので、ここでは考えないことにしました。

※ 2010年03月18日:追記
JIS X 0208:1997 のエスケープシーケンスは JIS X 0208-1990 と同じである事が分りましたので補足します。
参考) JIS X 0208:1997 -「9.2 指示」

shift_jis : 日本語 (シフト JIS)
コード体系
1 バイト目 2 バイト目 文字の種類
0x00~0x1F、0x7F 制御コード
0x20~0x7E ASCII文字
0xA1~0xDF 半角カタカナ
0x81~0x9F、0xE0~0xFC 0x40~0x7E、0x80~0xFC 漢字

※ ASCII のコードと重なっていますので注意が必要です。( euc-jp も怪しいですね... )

euc-jp : 日本語 (EUC)
コード体系
1 バイト目 2 バイト目 3 バイト目 文字の種類
0x00~0x1F、0x7F 制御コード
0x20~0x7E ASCII文字
0xA1~0xFE 0xA1~0xFE 漢字
0x8E 0xA1~0xDF 半角カタカナ
0x8F 0xA1~0xFE 0xA1~0xFE 補助漢字

※ ASCII のコードと重なっていますので注意が必要です。 (shift_jis も怪しいですね... )

UTF-8
コード体系
1 バイト目 2 バイト目 3 バイト目 4 バイト目 文字の種類
0x00~0x7F ASCII
0xC0~0xDF 0x80~0xBF 文字
0xE0~0xEF 0x80~0xBF 0x80~0xBF 文字
0xF0~0xF7 0x80~0xBF 0x80~0xBF 0x80~0xBF 文字
0xEF 0xBB 0xBF BOM ( Byte Order Mark )

※ ASCII のコードと重なっていますので注意が必要です。

※BOM ありの方を UTF-8 、なしの方を UTF-8N と呼ぶこともあります。

※BOM は、euc-jp のコードと重なっていますので注意が必要です。

文字コードの判定

ここでは、 ASCII, iso-2022-jp, shift_jis, euc-jp 及び UTF-8 の各文字コードの判定の順番等を (まだ未熟な...)私なりの考えでまとめてみましたので記述してみたいと思います。

  1. 7 ビットのコードである iso-2022-jp かどうかをチェックする

    0x00~0x7F の範囲外のコードが現れたら iso-2022-jp ではない
    0x00~0x7F の範囲内で、かつエスケープシーケンスのパターン が現れたら iso-2022-jp

  2. 7 ビットのコードである ASCII かどうかをチェックする

    0x00~0x7F の範囲外のコードが現れたら ASCII ではない
    文字列の最後まで 0x00~0x7F の範囲内なら ASCII

  3. shift_jis かどうかをチェックする

    コードが 0x00~0x7F ( ASCII ) 又は 0xA1~0xDF ( 半角カタカナ ) なら、次のバイトを調べる
    2 バイト以上 残っていて次の 2 バイトが shift_jis の漢字パターンに該当するなら、
     2 バイト先のバイトから繰り返し調べる
    途中で上記のいずれのパターンにも該当しないものがあれば shift_jis ではない
    文字列の最後まで上記のパターンに該当したら shift_jis

  4. euc-jp かどうかをチェックする

    コードが 0x00~0x7F ( ASCII ) なら、次のバイトを調べる
    2 バイト以上 残っていて次の 2 バイトが euc-jp の漢字又は半角カタカナのパターンに該当するなら、
     2 バイト先のバイトから繰り返し調べる
    又は 3 バイト以上 残っていて次の 3 バイトが euc-jp の補助漢字のパターンに該当するなら、
     3 バイト先のバイトから繰り返し調べる
    途中で上記のいずれのパターンにも該当しないものがあれば euc-jp ではない
    文字列の最後まで上記のパターンに該当したら euc-jp

  5. UTF-8 かどうかをチェックする

    コードが 0x00~0x7F ( ASCII ) なら、次のバイトを調べる
    2 バイト以上 残っていて次の 2 バイトが UTF-8 の 2 バイトの文字パターンに該当するなら、
     2 バイト先のバイトから繰り返し調べる
    又は 3 バイト以上 残っていて次の 3 バイトが UTF-8 の BOM に該当するなら、
     どこかに BOM ありの印をつけて 3 バイト先のバイトから繰り返し調べる
    又は 3 バイト以上 残っていて次の 3 バイトが UTF-8 の 3 バイトの文字パターンに該当するなら、
     3 バイト先のバイトから繰り返し調べる
    又は 4 バイト以上 残っていて次の 4 バイトが UTF-8 の 4 バイトの文字パターンに該当するなら、
     4 バイト先のバイトから繰り返し調べる
    途中で上記のいずれのパターンにも該当しないものがあれば UTF-8 ではない
    文字列の最後まで上記のパターンに該当したら UTF-8

私の頭では、この程度までしか考えられないのですが、言葉だけの説明だけでは何ですので
文字コードを判別して表示するサンプルコードを作成してみました。

完成度がどの程度なのかは自分でもよく分からないので、
サンプルコード : 文字コードの判定」 をご覧になって評価して頂けると幸いです。

※このサンプルコードでは、 UTF-8 のファイルが shift_jis ファイルと誤認識される場合があります。
文字コードの判定(補足)」も合わせて御覧ください。

Google Adsense
Google Adsense