我一直在使用i18n的东西一段时间,并且我认为我对此非常了解。但我正在测试一些东西,我看的越多,它就越糟糕。
我们从一个字符串开始:BoğaziçiÜniversitesi
它是由我们的富客户端应用程序(运行Windows并使用windows-1254)发送给我们的,解释为ISO-8859-1(不要问)并保存在MySQL数据库中。现在,在数据库中,我看到下面的字符值,可以解释为windows-1254:
42 6f f0 61 7a 69 e7 69 20 dc 6e 69 76 65 72 73 69 74 65 73 69
B o ğ a z i ç i Ü n i v e r s i t e s i
到目前为止,这么好。这看起来是字符串的正确形式。
但是,这是通过在字符串上运行getBytes()得到的,没有编码或编码不同:
BU.getBytes():( 21)42 6f 3f 61 7a 69 8d 69 20 86 6e 69 76 65 72 73 69 74 65 73 69
BU.getBytes(windows-1254):( 21)42 6f 3f 61 7a 69 e7 69 20 dc 6e 69 76 65 72 73 69 74 65 73 69
BU.getBytes(ISO-8859-1):( 21)42 6f f0 61 7a 69 e7 69 20 dc 6e 69 76 65 72 73 69 74 65 73 69
BU.getBytes(UTF8):( 24)42 6f c3 b0 61 7a 69 c3 a7 69 20 c3 9c 6e 69 76 65 72 73 69 74 65 73 69
所以,看看最后一个,人们不得不想知道“ð”的来源。
42 6f c3 b0 61 7a 69 c3 a7 69 20 c3 9c 6e 69 76 65 72 73 69 74 65 73 69
B o ð a z i ç i Ü n i v e r s i t e s i
从http://rishida.net/tools/conversion/开始,这是我期望获得的有效UTF-8字符串中的值:
42 6f C4 9F 61 7a 69 C3 A7 69 20 C3 9C 6e 69 76 65 72 73 69 74 65 73 69
B o ğ a z i ç i Ü n i v e r s i t e s i
在此处删除问题的最后部分并替换为。
此代码:
byte BU_Array[] = new byte[] { (byte)0x42, (byte)0x6F, (byte)0xF0, (byte)0x61,
(byte)0x7A, (byte)0x69,(byte)0xE7, (byte)0x69, (byte)0x20, (byte)0xDC,
(byte)0x6E, (byte)0x69, (byte)0x76, (byte)0x65, (byte)0x72, (byte)0x73,
(byte)0x69, (byte)0x74, (byte)0x65, (byte)0x73, (byte)0x69 };
try {
String BU_Str_ISO88591 = new String(BU_Array, "ISO-8859-1");
System.out.println("BU_Str_ISO88591 cP: "+codePointsToHex(BU_Str_ISO88591));
String BU_Str_W1254 = new String(BU_Array, "windows-1254");
System.out.println("BU_Str_W1254 cP: "+codePointsToHex(BU_Str_W1254));
byte bytes_possibly_as_utf8[] = BU_Str_W1254.getBytes("UTF-8");
System.out.println("bytes from BU_Str_W1254: "+Utilities.bytesToHex(bytes_possibly_as_utf8));
} catch (java.io.UnsupportedEncodingException uee) {
uee.printStackTrace();
}
产生
BU_Str_ISO88591 cP: (21): 42 6f f0 61 7a 69 e7 69 20 dc 6e 69 76 65 72 73 69 74 65 73 69
BU_Str_W1254 cP: (21): 42 6f 11f 61 7a 69 e7 69 20 dc 6e 69 76 65 72 73 69 74 65 73 69
bytes from BU_Str_W1254: (24) 42 6f c4 9f 61 7a 69 c3 a7 69 20 c3 9c 6e 69 76 65 72 73 69 74 65 73 69
这里令人困惑的是第1行中的第3个字符。
当我把一个字符串给了我们作为windows-1254但我们解释为iso-8859-1时,第三个字符的代码点是f0。这是Windows-1254中的正确字符。咦?那只是巧合吗?我对此表示怀疑,但逻辑似乎令人费解。
所以,我想我在这里回答了我自己的问题。