文字コードの判定
.NET Framework ではエンコーディングを指定してテキストファイルを読み込むことはできますが、
読み込もうとするテキストファイルがどのエンコーディングで作成されているかを知ることができないようです。
そのために、自分なりに文字コードを判定することを考えてみました。 ここでの目標は ASCII, iso-2022-jp, shift_jis, euc-jp 及び UTF-8 の各文字コードを判定することです。
※記述に誤りがあることに気がついた場合は、その内容を 「文字コードの判定(補足)」 に記述しますのであわせて御覧になってください。
- .NET Framework での 日本語文字コードの エンコーディング 一覧
- ASCII ( American Standard Code for Information Interchange )
- iso-2022-jp : 日本語 (JIS)
- shift_jis : 日本語 (シフト JIS)
- euc-jp : 日本語 (EUC)
- 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文字 と 半角カタカナ, 漢字, 補助漢字 のコード範囲が重複するため、
通常は次のような エスケープシーケンス によって切り替えます。
| 記号表記 | 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 の各文字コードの判定の順番等を (まだ未熟な...)私なりの考えでまとめてみましたので記述してみたいと思います。
-
7 ビットのコードである iso-2022-jp かどうかをチェックする
0x00~0x7F の範囲外のコードが現れたら iso-2022-jp ではない
0x00~0x7F の範囲内で、かつエスケープシーケンスのパターン が現れたら iso-2022-jp -
7 ビットのコードである ASCII かどうかをチェックする
0x00~0x7F の範囲外のコードが現れたら ASCII ではない
文字列の最後まで 0x00~0x7F の範囲内なら ASCII -
shift_jis かどうかをチェックする
コードが 0x00~0x7F ( ASCII ) 又は 0xA1~0xDF ( 半角カタカナ ) なら、次のバイトを調べる
2 バイト以上 残っていて次の 2 バイトが shift_jis の漢字パターンに該当するなら、
2 バイト先のバイトから繰り返し調べる
途中で上記のいずれのパターンにも該当しないものがあれば shift_jis ではない
文字列の最後まで上記のパターンに該当したら shift_jis -
euc-jp かどうかをチェックする
コードが 0x00~0x7F ( ASCII ) なら、次のバイトを調べる
2 バイト以上 残っていて次の 2 バイトが euc-jp の漢字又は半角カタカナのパターンに該当するなら、
2 バイト先のバイトから繰り返し調べる
又は 3 バイト以上 残っていて次の 3 バイトが euc-jp の補助漢字のパターンに該当するなら、
3 バイト先のバイトから繰り返し調べる
途中で上記のいずれのパターンにも該当しないものがあれば euc-jp ではない
文字列の最後まで上記のパターンに該当したら euc-jp -
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 ファイルと誤認識される場合があります。
「文字コードの判定(補足)」も合わせて御覧ください。