2013-11-27 110 views
2

我被要求修复我们的电子邮件处理软件中的错误。 当一个消息,其主题被编码在RFC 2047这样的:接收Base64中的日文字符编码

=?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 
配信テスト?日本語 

第一个较短的日文字符串是一个控件,它返回与输入相同的内容,已被转换为Base6 4,然后再使用Charset ISO-2022-JP。那里一切OK。

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

对不起,如果这很长,我想彻底。发生了什么,以及如何正确解码这个字符?

+0

尝试在编码中使用“MS932”。意思是私有静态最终字符集CHARSET = Charset.forName(“MS932”); – AJJ

+0

你尝试过使用SHIFT-JIS作为字符集吗? –

+0

嗯,但通常你应该将UTF-8转换为Base64 ...这会让它变得更容易。 –

回答

1

尝试在编码中使用“MS932”或“Shift-JIS”。意味着

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

有在日本像汉字,片假名不同的脚本。一些像Cp132这​​样的编码将不支持某些日文字符。您所面临的问题是因为您在代码中使用了“ISO-2022-JP”编码。

1

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

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

0

尽管ISO-2022-JP是一个可变宽度编码的事实,它似乎好像Java不支持它所在的字符集部分(可能是由于ISO-2022-JP-2中存在的缺失转义序列ISO-2022-JP-3ISO-2022-JP-2004不支持)。 UTF-8,UTF-16UTF-32不过支持所有的字符。

UTF-32:

AAB+SwAAMEwAADBjAAAwZg== 
繋がって 
AACRTQAAT+EAADDGAAAwuQAAMMgAADIxAABl5QAAZywAAIqe 
配信テスト㈱日本語 

作为一个额外的珍闻,不管UTF-32是否被使用的,当字符串印原样他们保留其天然编码和出现正常。

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字符集规范的较新版本)中。