一段java代碼帶你認識錕斤拷

@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();
  }


}
發佈了150 篇原創文章 · 獲贊 119 · 訪問量 73萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章