異なるプラットフォーム間の通信、ソフトウェア間の通信、または、データベース処理を行う際に文字化けの問題がよく発生します。たとえば、SolarisマシンからWindowsマシンにネットワーク経由で全角のチルダ('~')を送ると、Windowsマシンで'?'が表示されるというものです。
特に、Javaの場合は内部でUnicodeを扱うという特性があるため、文字コード変換処理の過程でUnicodeに変換する処理が間に入り、文字化けが発生しやすくなります。そのため、開発者はこのような文字化けの問題を避けるための自衛的手段を講じる必要があります。
Unicodeの特徴
UnicodeはUnicodeコンソーシアムが規定した文字コード体系です。世界の主要な言語のほとんどの文字を収録し、1つの文字コード体系で多国語処理を可能にしようという目的で策定されたものです。
Unicodeは主要な言語のほとんどの文字を収録しようとしたわけですが、この過程で次の特徴が生まれました。
似たような文字が多数収録されている
Unicodeでは、見た目が同じような文字であっても役割や用途が異なる文字は別文字として収録されています。
たとえば、全角のチルダ記号('~'、JIS X 0208の01区33点、WAVE DASH)に似た文字として、「JIS X 0208 01-33に似たUnicode文字」の6種類の文字が収録されています。
全角・半角を別文字として収録している
Unicodeでは、既存のコード系との互換性を保証するために、全角・半角を別文字として収録しています。
たとえば、全角の'A'と半角の'A'はUnicodeでは異なる文字として収録されています。 また、'£'や'¢'などのように日本語のコード系では全角の文字しかないものも、Unicodeでは全角・半角の2種類の文字が収録されています。
コードポイント | 登録名 |
---|---|
U+301c | WAVE DASH |
U+223c | TILDE OPERATOR |
U+223d | REVERSED TILDE |
U+223e | INVERTED LAZY S |
U+223f | SIGN WAVE |
U+ff5e | FULLWIDTH TILDE |
文字化けが起きる仕組み
このようにUnicodeには似たような文字が多数収録されているので、日本語の文字をUnicodeのどの文字に対応させるかという変換規則が文字コンバーターによって異なります。
一例としてJDK/JRE 5.0における文字の違いを、「JDK/JRE 5.0における文字の違い」に示します。
eucJP-Solaris |
| Unicode (Java) |
| Windows-31J |
---|---|---|---|---|
0xa1c1('~') | → | U+301c | → | 0x3f |
0x8fa2b7 | ← | U+ff5e | ← | 0x8160('~') |
'~'の文字コードは、eucJP-Solarisでは0xa1c1で、Windows-31では0x8160です。
しかし、「JDK/JRE 5.0における文字の違い」によると、eucJP-Solarisの0xa1c1と、Windows-31の0x8160は相互変換できないことがわかります。
異なるプラットフォーム間の通信、ソフトウェア間の通信、データベース処理などは、複数の文字コンバーターを介して文字列を変換することが多いので、文字化けが発生しやすい環境です。そのため、開発者は事前に自衛的手段を講じて、文字化けを防ぐようにしてください。
日本語変換できないデータの扱い
入力データに変換不可能なコードが指定された場合のJavaの動作は不定です。そのため、JDK/JREのバージョンにより、全体が'?'に変換される場合や、部分的に'?'に変換される場合があります。入力データに日本語変換不可能なデータを設定しないで下さい。