文字化けが発生するのはいくつかの原因があります。
ブラウザなどは、ドキュメントの漢字コードを自動判別します。しかし、漢字コードマップから解るように、シフトJISとEUCのコードが一部(紫部分)重複しているために、EUCのファイルをシフトJISのファイル(またはその逆)と誤判定し、文字化けが発生することがあります。(→文字化けしないようにするには)
CGI利用のページで「表示」が「侮ヲ」に化けたりするケースです。「表示」をシフトJISのコードで表わすと「95 5c 8e a6」となりますが、この 5c はバックスラッシュ(\)と同じコードであり、これをperlが \n や \t のような特別な値(エスケープシーケンス)だと思って処理してしまうことに原因があります。一度EUCに変換して処理したり、「表\示」のように余分なバックスラッシュ(\)を記述することにより回避できます。
日本語対応されていないFTPソフトのテキストモード(ASCIIモード)でファイルを転送する際に、文字化けが発生することがあります。これは、FTPが転送効率を上げるために、テキストモードでは文字コードのトップビットを落として転送することにより発生します。
その他にも、電子メールをEUCやシフトJISで送信したために、途中のメール転送ソフトが文字コードのトップビットを落としてしまうために発生したりすることがあります。
Java では、JIS X 0208 の文字集合のみを扱う「SJIS」と、これに「NEC特殊文字」、「NEC選定IBM拡張文字」、「IBM拡張文字」を加えた「MS932」という2つのコード名があります。また、「Shift_JIS」というコード名もあるのですが、下記の様にバージョンによって仕様が異なるため、Shift_JIS は用いず、SJIS または MS932 を使用するのがよいようです。
バージョン | SJIS | Shift_JIS | MS932 |
---|---|---|---|
Java 1.1 まで | SJIS | SJISと同義 | 未サポート |
Java 1.1.8~1.4.0 | SJIS | MS932と同義 | MS932 |
Java 1.4.1以降 | SJIS | SJISと同義 | MS932 |
c1を第一バイト、c2を第二バイトとします。EUC→SJISは(1)と(3)を、SJIS→EUCは(4)と(2)を組み合わせてください。
(1) EUC から JIS(ISO-2022-JP)に変換
c1 = c1 - 0x80; c2 = c2 - 0x80;
(2) JIS から EUC に変換
c1 = c1 + 0x80; c2 = c2 + 0x80;
(3) JIS から シフトJIS に変換
if (c1 % 2) { c1 = ((c1 + 1) / 2) + 0x70; c2 = c2 + 0x1f; } else { c1 = (c1 / 2) + 0x70; c2 = c2 + 0x7d; } if (c1 >= 0xa0) { c1 = c1 + 0x40; } if (c2 >= 0x7f) { c2 = c2 + 1; }
(4) シフトJIS から JIS に変換
if (c1 >= 0xe0) { c1 = c1 - 0x40; } if (c2 >= 0x80) { c2 = c2 - 1; } if (c2 >= 0x9e) { c1 = (c1 - 0x70) * 2; c2 = c2 - 0x7d; } else { c1 = ((c1 - 0x70) * 2) - 1; c2 = c2 - 0x1f; }