LoginSignup
9
14

More than 5 years have passed since last update.

JavaでSHIFT-JISを見つけたら要注意

Posted at

経緯

Javaで作成したWEBアプリケーションにで"~"が文字化けするという不具合があった。
DBの文字コードがUTF-8、CSV出力がMS932であったため、異なる文字コードの変換による文字化けかと思って調査していたら、もっと単純な話だった。
結構時間を無駄にしたので、メモもかねて残しておく。

原因

DBがUTF-8でも、Javaでは内部表現であるUTF16になるため、ここでは問題ない。
処理を追っていると、DBからデータ取得後、Javaの処理でSHIFT-JISに変換してからMS932に変換していた。"~"で出てくるSHIFT-JIS, MS932の変換問題かと思ったら、SHIFT-JIS、UTF16(Javaの内部表現)の変換問題だった。

文字変換例

簡単なソースコードを作成して検証してみた。(java:1.8.0_121)
SHIFT-JISとMS932のバイト配列に変換してから、Javaの文字列を生成するとSHIFT-JISだけ文字化けが発生している。

        String org = "~";

        byte[] sjBytes = org.getBytes("SHIFT-JIS");
        byte[] ms932Bytes = org.getBytes("MS932");

        String sj = new String(sjBytes, "SHIFT-JIS");
        String ms932 = new String(ms932Bytes, "MS932");

        String fmt = "%s\t文字列:%s, バイト配列:%s";
        System.out.println(String.format(fmt, "元の文字", org, DatatypeConverter.printHexBinary(org.getBytes())));
        System.out.println(String.format(fmt, "SHIFT-JIS", sj, DatatypeConverter.printHexBinary(sjBytes)));
        System.out.println(String.format(fmt, "MS932", ms932, DatatypeConverter.printHexBinary(ms932Bytes)));

出力結果

元の文字 文字列:~, バイト配列:EFBD9E
SHIFT-JIS 文字列:?, バイト配列:3F
MS932 文字列:~, バイト配列:8160

まとめ

そもそもUTF-8にすれば問題ないけど、仕様変更になるため扱いが厄介。
どうしてもSHIFT-JISを使いたい場合はMS932で十分なので、SHIFT-JISは使用しない。

目次

9
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
14