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になるようだ。これは知らなかった。
以下、ちょっとした確認。
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なのか…。