ablog

不器用で落着きのない技術者のメモ

MS932(Java) + JA16SJIS(Oracle) でチルダ「〜(0x8160)」が文字化けする理由

Java の MS932 エンコーディングSJIS<->Unicode 対応表と
Oracle Database の JA16SJIS キャラクタセットSJIS<->Unicode 対応表が異なるため。


例えば、Webアプリにユーザが「〜(0x8160)」を入力すると、Oracle Database に 0x8160 で保存される。
ここまでは無問題。
次に Oracle Database に保存された 0x8160 をWebアプリで表示しようとすると問題が起こる。
Oracle Database は 0x8160 を U+301C に変換して、JVM に渡すが、JVMUnicode->SJIS 対応表に U+301C は存在しないため「?」となる。


MS932 と JA16SJIS の SJIS<->Unicode 対応表は以下のように異なり、

変換方向 MS932 JA16SJIS
SJISUnicode 0x8160 → U+FF5E 0x8160 → U+301C
UnicodeSJIS U+FF5E → 0x8160 U+301C → 0x8160
U+FF5E → 0x8160*1

従って、

ブラウザ -- 0x8160

JVM で変換 -- 0x8160 -> U+FF5E

Oracle で変換 -- U+FF5E -> 0x8160

Oracle に保存 -- 0x8160

Oracle で変換 -- 0x8160 -> U+301C

JVM で変換 -- U+301C -> ?

ブラウザ -- ?

という具合にチルダが文字化けする。

この問題を回避するために生まれたキャラクタセットJA16SJISTILDE

*1:8.1.6以降