@Test
public void testKunJinKao(){
String str="我不是錕斤拷";
try {
byte[] buff=null;
//讓我們先看看幾種錯誤的轉換,let's go
//1. 正常的GBK字節流,你以爲是UTF-8,所以用UTF-8去解碼...
buff=str.getBytes("GBK");//這裏只要不拋異常,數據一定不會被破壞
String str1=new String(buff,"UTF-8");
System.out.println(str1);//這是一種情形:���
//2. 正常的UTF-8字節流,你以爲是GBK,所以用GBK去解碼...
buff=str.getBytes("UTF-8");//這裏只要不拋異常,數據一定不會被破壞
String str2=new String(buff,"GBK");//這裏破壞了
System.out.println(str2);//這是另外一種情形:
//說了半天,錕斤拷在哪裏呢?come on
//3. 本來正常的GBK字節碼,在你不知道的某個環節已經被錯誤的使用UTF-8解碼了
String str3=new String(str.getBytes("GBK"),"UTF-8");
String str4=new String(str3.getBytes("UTF-8"),"GBK");//這裏你並不知道數據已經破壞了,這樣用是對的。
System.out.println(str4);//錕斤拷
/**
* Got it.How are you,nice to meet you.
*
* Why?
* 如果說情形1、2是開發者自己造成的,
* 那麼情形3往往是開發者被坑了,別人造成的(也可能是容器層),總之你拿到的時候已經亂了。
*/
/**
* 細心的你會發現,正是情形1的錯誤,導致了情形3的發生。之所以表現不同,是因爲情形1的程序猿是在UTF-8下打印輸出;
* 而情形3是在GBK下打印輸出。
*/
/**
* 總結一下,錕斤拷是怎麼產生的?
*
* 源於GBK字符集和Unicode字符集之間的轉換問題。
* Unicode和老編碼體系的轉化過程中,肯定有一些字,用Unicode是沒法表示的,
* Unicode官方用了一個佔位符(REPLACEMENT CHARACTER)來表示這些文字,這就是:U+FFFD
*
* U+FFFD的UTF-8編碼出來,恰好是 '\xef\xbf\xbd'。
*
* 重複多次,例如 '\xef\xbf\xbd\xef\xbf\xbd',
* 然後放到GBK/CP936/GB2312/GB18030的環境中顯示的話,
* 一個漢字2個字節,最終的結果就是:錕斤拷——錕(0xEFBF),斤(0xBDEF),拷(0xBFBD)。
*/
} catch (Exception e) {
e.printStackTrace();
}
}
一段java代碼帶你認識錕斤拷
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.