| Symfoware(R) Server JDBCドライバユーザーズガイド - FUJITSU - |
目次
索引
![]()
|
第2章 システム設計の考え方
2.2 文字コード流通
Javaで異機種間結合を行う場合、あるいは、データベース接続を行う場合に起こる問題の1つに、文字化けの問題があります。例えば、Solaris OEマシンからWindowsマシンにネットワークを介して全角のチルダ記号('〜')を送ると、Windowsマシンで表示したときに文字化けしてしまうことがあります。
これは既存の日本語コード(JIS、EUC、シフトJIS)をUnicodeに変換する際の変換規則が各ベンダによって異なるために起きる問題です。この問題はJavaで解決できるものではなく、Javaのシステム開発者がこの問題を避けるための自衛的手段を講じる必要があります。
この問題を理解するには、この問題が起きた背景を理解する必要があります。
以下ではその背景を説明します。
UnicodeはUnicodeコンソーシアムが規定した文字コード体系です。世界の主要な言語のほとんどの文字を収録し、1つの文字コード体系で多国語処理を可能にしようという目的で策定されたものです。Unicodeは国際標準化機構(ISO)の規格であるISO/IEC 10646のベースになっています。
Unicodeは主要な言語のほとんどの文字を収録しようとした訳ですが、この過程で次のような特徴が生まれました。
Unicodeは、見た目が同じような文字であっても役割や用途が異なる文字は別文字として収録する、という方針で策定されています。例えば全角のチルダ記号('〜'、JIS X 0208では WAVE DASH(01-33))に似た文字は、以下のように6種類も収録されています。
|
コードポイント |
登録名 |
|---|---|
|
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では、既存のコード系との互換性を保証するために、全角と半角を別文字として収録しています。例えば全角の'A'と半角の'A'はUnicodeでは異なる文字として収録されています。
しかし、'£'や'¢'などのように日本語のコード系では全角の文字しかないものも、Unicodeでは全角と半角の2種類の文字が収録されています。
|
コードポイント |
登録名 |
|---|---|
|
U+00a3 |
POUND SIGN |
|
U+ffe1 |
FULLWIDTH POUND SIGN |
|
コードポイント |
登録名 |
|---|---|
|
U+00a2 |
CENT SIGN |
|
U+ffe0 |
FULLWIDTH CENT SIGN |
このようにUnicodeには似たような文字が多数収録されているので、既存の日本語コード系の文字をUnicodeのどの文字に対応させるべきか、いろいろな解釈が出てきます。ベンダごとの解釈が異なるために、実際に各ベンダの変換規則に違いが出ています。代表的な例を以下に挙げます。
JISでもJIS X 0221の付属書でJIS漢字とUnicodeの変換規則を定義しています。この2つで全角のダッシュ記号(JIS X 0201 01-29、'*')の変換規則が異なります。

Windowsの変換規則では日本語コードの全角文字はUnicodeの全角文字に対応させるというのが基本方針で、そのためJISの変換規則と異なる文字がいくつかあります。
|
JIS X 0208 |
Unicodeへの変換 |
|---|---|
|
01-33 |
JIS:U+301c |
|
Windows:U+ff5e |
|
|
01-82 |
JIS:U+00a3 |
|
Windows:U+ffe1 |
|
|
01-81 |
JIS:U+00a2 |
|
Windows:U+ffe0 |
これらの変換規則は、どれが正しくてどれが間違っているというものではありません。JISで定義されている変換規則はあくまでも参考であり、強制力を持つものではありません。どの文字をどの文字に対応させるかは、最終的には変換規則を作成する各ベンダに任せられているのが現状です。
このように各ベンダにより変換規則が異なるために、Javaで異ベンダのシステムを連携させたときに、いくつかの文字が文字化けすることになります。
例として、JavaでSolaris OEとWindowsをネットワーク接続し、テキストデータをやりとりするシステムを考えてみます。
|
EUCデータ |
|
Java(Unicode) |
|
シフトJISデータ |
|---|---|---|---|---|
|
'〜' |
→ |
U+301c |
→ |
未定義 |
|
未定義 |
← |
U+ff5e |
← |
'〜' |
Javaはプラットフォーム固有のコード系の文字データを読み込み、それをUnicodeに変換して処理します。データがネットワーク転送される際にはUnicode形式で送られ、それが他方のプラットフォーム固有のコード系に変換し直されます。
この例ではSolaris OE上でのコード系にEUCを用いることにします。Solaris OE上のEUCとUnicodeの相互変換はJISの変換規則に従ったものです。Javaも基本的にはJISの変換規則に従ってEUCとUnicodeの相互変換を行います。
Windowsの方ではコード系にシフトJISを用いることにします。WindowsにはWindowsのコード変換規則があるので、JavaもWindowsの変換規則に従ってシフトJISとUnicodeの相互変換を行います。
ここで、Solaris OEからWindowsに全角のチルダ文字('〜')を送る場合を考えてみます。
この逆も同じことで、Windows上の'〜'(U+ff5e)をSolaris OEに送った場合にも、JISの変換規則ではU+ff5eに対応する文字が定義されていないため、EUCに変換したときには未定義文字になってしまいます。
Solaris OE上のコード変換もWindows上のコード変換も変換規則に問題はなく、Javaもそれに従って正しい変換を行っています。しかしそれぞれの変換規則が異なるために、2つの規則を組み合わせたときに正しい変換が行われなくなってしまいます。
これらの問題は一方の変換規則をもう一方に合わせれば解決するように見えますが、そうすると今度は変換規則を変えた方で別の不整合が起こります。
例えば始めの例で、Windows側の変換規則をJISの変換規則に変えてしまうと、Solaris OEから送られてきたUnicodeデータは正しく変換できるようになりますが、Windows上に保存されている既存のUnicodeデータが正しく変換できなくなります。
最も単純かつ確実な対処方法は、文字化けが起きる文字をシステムで使わないようにすることです。文字化けが起きる文字はごく限られた少数のマルチバイト文字のみです。システム設計時にそれらの文字を使用しないよう注意する必要があります。
あるいは、サーバがSolaris OEでクライアントがWindowsであるといったように使用するプラットフォームやデータベースが特定できる場合には、データ転送時にフィルタを掛けるという対処法もあります。
例えば、Solaris OEからWindowsに文字データを送信する際に、データ内に現れるU+301cをすべてU+ff5eに変換してから転送すれば、Solaris OEからWindowsに正しく'〜'が送られるようになります。
いずれにせよ、異なるベンダのシステムをつないだシステム開発を行う際には、システム開発者が事前に自衛的手段を講じて、文字化けの問題が起きるのを防ぐ必要があります。

以下は、Javaで前述の例(Solaris OEとWindowsでのネットワーク通信を行うシステム)を実現した場合に文字化けが起きる文字の一覧です。

目次
索引
![]()
|