2013-11-27 214 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字符集規範的較新版本)中。