Javaでメールを送るときなどに、ふつうのISO-2022-JP でエンコードすると丸付き数字とか、草ナギ剛の「なぎ」とかが文字化けしたりする。
これの暫定対策として、JDK 5.0 update7 から、CP50220 などのエンコーディングが追加されていて、これを使うとそういった文字も文字化けしなくなる。
http://www.yks.ne.jp/~tsurucha/ChangeLog/2007-03.html#2007-03-22
ってとこまでは聞いたことがあったんだけど、全角ダッシュ(uFF0D)とかポンド記号(uFFE1)みたいな、今まで手動で代わりの文字(u2212とか)に変換して対処していたようなものも、このエンコーディングだとそのままOKになるようだ。これは知らなかった。
以下、ちょっとした確認。
1.5.0_13-b05 で実行したときのresult.txtの中身。
gooブログってEUCなのか…。
これの暫定対策として、JDK 5.0 update7 から、CP50220 などのエンコーディングが追加されていて、これを使うとそういった文字も文字化けしなくなる。
http://www.yks.ne.jp/~tsurucha/ChangeLog/2007-03.html#2007-03-22
ってとこまでは聞いたことがあったんだけど、全角ダッシュ(uFF0D)とかポンド記号(uFFE1)みたいな、今まで手動で代わりの文字(u2212とか)に変換して対処していたようなものも、このエンコーディングだとそのままOKになるようだ。これは知らなかった。
以下、ちょっとした確認。
import java.io.*; import java.nio.*; import java.nio.charset.*; public class EncodeChecker { public static void main(String[] args) throws Exception { // 怪しげな文字。以下からいただきました。 // http://www.ingrid.org/java/i18n/encoding/ja-conv.html char[] chars = { '\\', '\u007E', '\u00A2', '\u00A3', '\u00AC', '\u00A5', '\u203E', '\u2014', '\u2015', '\u2016', '\u2026', '\u2212', '\u2225', '\u301C', '\u22EF', '\uFF0D', '\uFF5E', '\uFFE0', '\uFFE1', '\uFFE2', '\uFFE3', '\u2160', '\u2468', '\u3231', '\u3336', '\u5F45', }; PrintWriter writer = new PrintWriter(new File("result.txt"), "UTF-8"); checkAll(writer, "ISO-2022-JP", chars); writer.println(); checkAll(writer, "CP50220", chars); writer.close(); } private static void checkAll(PrintWriter writer, String encoding, char[] target) throws UnsupportedEncodingException { EncodeChecker checker = new EncodeChecker(encoding); writer.println(String.format("# %s", encoding)); for (char c : target) { writer.write(checker.check(c)); writer.println(); } } private CharsetEncoder encoder; public EncodeChecker(String encoding) throws UnsupportedEncodingException { Charset charset = Charset.forName(encoding); encoder = charset.newEncoder() .onMalformedInput(CodingErrorAction.REPORT) .onUnmappableCharacter(CodingErrorAction.REPORT); } public String check(char c) { StringBuilder result = new StringBuilder(); result.append(String.format("\\u%04X [%c] : ", (int)c, c)); CharBuffer cb = CharBuffer.wrap(new char[]{c}); ByteBuffer bb = ByteBuffer.allocate(10); CoderResult cr = encoder.encode(cb, bb, true); if (cr.isUnderflow()) { result.append("○ [ "); int len = bb.position(); for (int i=0; i<len; i++) { result.append(String.format("%02X ", bb.get(i))); } result.append("]"); } else if (cr.isError()) { result.append("×"); } else { result.append("?"); } return result.toString(); } }
1.5.0_13-b05 で実行したときのresult.txtの中身。
# ISO-2022-JP u005C [\] : ○ [ 5C ] u007E [~] : ○ [ 7E ] u00A2 [¢] : ○ [ 1B 24 42 21 71 ] u00A3 [£] : ○ [ 21 72 ] u00AC [¬] : ○ [ 22 4C ] u00A5 [] : ○ [ 1B 28 4A 5C ] u203E [~] : ○ [ 7E ] u2014 [―] : ○ [ 1B 24 42 21 3D ] u2015 [―] : × u2016 [∥] : ○ [ 21 42 ] u2026 […] : ○ [ 21 44 ] u2212 [-] : ○ [ 21 5D ] u2225 [∥] : × u301C [~] : ○ [ 21 41 ] u22EF […] : × uFF0D [-] : × uFF5E [~] : × uFFE0 [¢] : × uFFE1 [£] : × uFFE2 [¬] : × uFFE3 [ ̄] : ○ [ 21 31 ] u2160 [Ⅰ] : × u2468 [⑨] : × u3231 [㈱] : × u3336 [㌶] : × u5F45 [] : × # CP50220 u005C [\] : ○ [ 5C ] u007E [~] : ○ [ 7E ] u00A2 [¢] : ○ [ 1B 24 42 21 71 ] u00A3 [£] : ○ [ 21 72 ] u00AC [¬] : ○ [ 22 4C ] u00A5 [] : ○ [ 1B 28 4A 5C ] u203E [~] : ○ [ 7E ] u2014 [―] : × u2015 [―] : ○ [ 1B 24 42 21 3D ] u2016 [∥] : ○ [ 21 42 ] u2026 […] : ○ [ 21 44 ] u2212 [-] : ○ [ 21 5D ] u2225 [∥] : ○ [ 21 42 ] u301C [~] : ○ [ 21 41 ] u22EF […] : × uFF0D [-] : ○ [ 21 5D ] uFF5E [~] : ○ [ 1B 24 28 44 22 37 ] uFFE0 [¢] : ○ [ 1B 24 42 21 71 ] uFFE1 [£] : ○ [ 21 72 ] uFFE2 [¬] : ○ [ 22 4C ] uFFE3 [ ̄] : ○ [ 21 31 ] u2160 [Ⅰ] : ○ [ 2D 35 ] u2468 [⑨] : ○ [ 2D 29 ] u3231 [㈱] : ○ [ 2D 6A ] u3336 [㌶] : ○ [ 2D 47 ] u5F45 [] : ○ [ 1B 24 28 44 3C 74 ]
gooブログってEUCなのか…。