Base64中的日文字符编码

时间:2013-11-27 11:09:00

标签: java encoding base64 mime

我被要求修复我们的电子邮件处理软件中的错误。 当主题以RFC 2047编码的邮件时,如下所示:

=?ISO-2022-JP?B?GyRCR1s/LiVGJTklSC1qRnxLXDhsGyhC?=
收到

,它被错误解码 - 其中一个日文字符未正确呈现。它是这样呈现的:配信テスト?日本语何时应该是配信テスト㈱日本语 (我不懂日语) - 很明显其中一个字符,即括号中的字符,尚未呈现。

解码由javax.mail.internet.MimeUtility.decodeText()

执行

如果我使用在线解码器(我发现的唯一一个here)尝试它似乎工作正常,所以我怀疑MimeUtility中的错误。

所以我尝试了一些小程序的实验:

public class Encoding {

  private static final Charset CHARSET = Charset.forName("ISO-2022-JP");

  public static void main(String[] args) throws UnsupportedEncodingException {

        String control = "繋がって";
        String subject= "配信テスト㈱日本語";            

        String controlBase64 = japaneseToBase64(control);
        System.out.println(controlBase64);
        System.out.println(base64ToJapanese(controlBase64));

        String subjectBase64 = japaneseToBase64(subject);
        System.out.println(subjectBase64);
        System.out.println(base64ToJapanese(subjectBase64));

  }

  private static String japaneseToBase64(String in) {
        return Base64.encodeBase64String(in.getBytes(CHARSET));
  }

  private static String base64ToJapanese(String in) {
        return new String(Base64.decodeBase64(in), CHARSET);
  }

}

Base64Hex类位于org.apache.commons.codec

当我运行它时,这是输出:

GyRCN1IkLCRDJEYbKEI=
繋がって
GyRCR1s/LiVGJTklSCEpRnxLXDhsGyhC
配信テスト?日本語

第一个较短的日语字符串是一个控件,它使用Charset ISO-2022-JP返回与输入相同的内容,已经转换为Base64并再次返回。一切都好。

第二个日语字符串是具有狡猾字符的字符串。如你所见,它返回一个?而不是角色。 Base64编码输出也与原始主题编码不同。

对不起,如果这很长,我想要彻底。发生了什么,我该如何正确解码这个角色?

4 个答案:

答案 0 :(得分:2)

该错误不在您的软件中,但主题字符串本身编码不正确。其他软件可以通过对内容做出进一步假设来解码文本,就像通常假设0x80-0x9f范围内的字符是Cp1252编码一样,尽管指定了ISO-8859-1或ISO-8859-15

ISO-2022-JP是一种多字符集编码,使用转义序列在实际使用的字符集之间切换。您的编码字符串以ESC $ B开头,表示使用了字符集JIS X 0208-1983。违规字符编码为0x2d6a。该代码点未在引用的字符集中定义,但后来添加到JIS X 0213:2000中,这是JIS X字符集规范的较新版本。

答案 1 :(得分:1)

尝试在编码中使用“MS932”或“Shift-JIS”。手段

private static final Charset CHARSET = Charset.forName("MS932"); 

日本有不同的剧本,如汉字,片假名。像Cp132这​​样的编码不支持日文的某些字符。您遇到的问题是您在代码中使用的编码“ISO-2022-JP”。

答案 2 :(得分:1)

ISO-2022-JP使用称为ku和10的字节对,它们索引到一个94×94的字符表中。失败的对有ku 12和ten 73,它没有列在我有效的字符表中(基于JIS X 0208)。所有ku = 12似乎都没用了。

维基百科也没有列出对JIS X 0208的任何更新。也许发件人正在使用某种供应商定义的扩展名?

答案 3 :(得分:0)

尽管ISO-2022-JP是一个可变宽度编码,但似乎Java不支持它所在的字符集部分(可能是{{}中缺少转义序列的结果。存在于ISO-2022-JP-2ISO-2022-JP-3中且不受支持的1}}。 ISO-2022-JP-2004UTF-8UTF-16会支持所有角色。

UTF-32:

UTF-32

作为额外的花絮,无论是否使用AAB+SwAAMEwAADBjAAAwZg== 繋がって AACRTQAAT+EAADDGAAAwuQAAMMgAADIxAABl5QAAZywAAIqe 配信テスト㈱日本語 ,当字符串按原样打印时,它们都会保留其自然编码并正常显示。