UTF-8編碼與GBK編碼之間的轉換

atlantisholic發表於2011-11-14

.先看一段程式碼

下面一段程式碼,將字串在GBKUTF-8之間進行兩次轉換,第一次生成亂碼(UTF-8的位元組碼用GBK解析),第二次反推這個過程,應該會生成正確的字串.
但是有些中文字卻變成了'???'一類的亂碼.只是其中的一些...

private static void print(byte[] bs){

       for(byte b:bs)

           System.out.print(Integer.toHexString(b).replace("ff","")+" ");

       System.out.println();

    }

    public static void main(String[] args) throws UnsupportedEncodingException {

       String utf8="UTF-8";

       String gbk="GBK";

      

       String source="可憐";

       byte[] sourcebyte=source.getBytes(utf8);

       //將字串轉換成UTF-8編碼

       System.out.println(source);

       //列印原字串

       print(sourcebyte);

       //================================================

       String temp=new String(sourcebyte,gbk);

       //使用字串生成的UTF-8編碼生成GBK編碼字串

       System.out.println(temp);

       //列印結果亂碼,意料之中,因為UTF-8中文3位元組,而GBK中文大多為雙位元組,能匹配成功就非亂碼,否則使用??替代

       //================================================

       byte[] targetbyte=temp.getBytes(gbk);

       String target=new String(targetbyte,utf8);

       System.out.println(target);

       //列印最終字串

       print(targetbyte);

    }

上面的程式碼會列印出:
可憐

e5 8f af e6 80 9c

???

???

e5 8f af e6 3f 3f

.結果解析

1 程式中使用了UTF-8 —》GBK —》UTF-8,整個是一個轉換和逆轉換的過程,按照原先的設想,應該列印出原來的輸入值“可憐”,而結果卻出現了亂碼,中間這個轉換的具體細節是什麼樣的呢?

2 先使用UTF-8,將字串轉換成位元組形式,UTF-8在中文狀態下為3位元組編碼,而兩個漢字是6個位元組。

3 將生成的UTF-8位元組使用GBK編碼轉換成字串,GBK在中文狀態下為2位元組編碼,如果能匹配,正好3個漢字,看一下GBK編碼範圍:

名稱

第一位元組

第二位元組

GB2312

0xB0-0xF7(176-247)

0xA0-0xFE160-254

GBK

0x81-0xFE129-254

0x40-0xFE64-254

Big5

0x81-0xFE129-255

0x40-0x7E64-126

0xA10xFE161-254

編碼1~2: e5 8f 高位元組位符合,低位元組位也符合,列印結果:

編碼3~4: af e6 高位元組位符合,低位元組位也符合,列印結果:(空格)

編碼5~6: 80 9c 高位元組位不符合,低位元組位符合,未能找到結果,以??替代

 

4. 使用GBK,將字串轉換成位元組形式,前4個位元組因為能在GBK中找到,所以原樣輸出了,而最後兩個位元組80 9c無法找到,被替換成了??,所以被轉換成了位元組3f 3f(3f十進位制63,即?的編碼)

 

5. 最後再次使用UTF-8編碼將逆向轉換回來的位元組轉換成字串時,前3個位元組可以正常輸出為漢字,而第4個位元組未能找到,顯示為?,第56個位元組正常輸出都為?

 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23071790/viewspace-710925/,如需轉載,請註明出處,否則將追究法律責任。

相關文章