Java 中文字符串編碼之GBK轉UTF-8

寫過兩篇關於編碼的文章了,覺得本身比較瞭解編碼了呢?!測試

結果今天又結結實實的上了一課。編碼

之前轉來轉去解決的問題終歸仍是簡單的情形。即iso-8859-1轉utf-8,或者iso-8859-1轉gbk,gb2312之類。這種無損轉換,一行代碼就搞定。spa

今天遇到了gbk轉utf-8。不管怎麼轉,都是亂碼。code

1、亂碼的緣由blog

gbk的中文編碼是一個漢字用【2】個字節表示,例如漢字「內部」的gbk編碼16進制的顯示爲c4 da b2 bfutf-8

utf-8的中文編碼是一個漢字用【3】個字節表示,例如漢字「內部」的utf-8編碼16進制的顯示爲e5 86 85 e9 83 a8字符串

很顯然,gbk是沒法直接轉換成utf-8,少字節變爲多字節,誰知道缺乏的字節是什麼啊?!get

2、轉換的辦法io

有辦法實現「有損」轉換嗎?答案是確定的。class

1.首先將gbk字符串getBytes()獲得兩個原始字節,轉換成二進制字符流,共16位。

2.根據UTF-8的漢字編碼規則,首字節以1110開頭,次字節以10開頭,第3字節以10開頭。在原始的2進制字符串中插入標誌位。最終的長度從16--->16+4+2+2=24。

3.轉換完成,實際狀況須要考慮更多因素,例如字符串是漢字和數字的混合體,須要識別處理數字。

3、不要重複發明輪子

這段代碼測試可用還很好用,須要的能夠參考。

 1 public static String getUTF8StringFromGBKString(String gbkStr) {  
 2         try {  
 3             return new String(getUTF8BytesFromGBKString(gbkStr), "UTF-8");  
 4         } catch (UnsupportedEncodingException e) {  
 5             throw new InternalError();  
 6         }  
 7     }  
 8       
 9     public static byte[] getUTF8BytesFromGBKString(String gbkStr) {  
10         int n = gbkStr.length();  
11         byte[] utfBytes = new byte[3 * n];  
12         int k = 0;  
13         for (int i = 0; i < n; i++) {  
14             int m = gbkStr.charAt(i);  
15             if (m < 128 && m >= 0) {  
16                 utfBytes[k++] = (byte) m;  
17                 continue;  
18             }  
19             utfBytes[k++] = (byte) (0xe0 | (m >> 12));  
20             utfBytes[k++] = (byte) (0x80 | ((m >> 6) & 0x3f));  
21             utfBytes[k++] = (byte) (0x80 | (m & 0x3f));  
22         }  
23         if (k < utfBytes.length) {  
24             byte[] tmp = new byte[k];  
25             System.arraycopy(utfBytes, 0, tmp, 0, k);  
26             return tmp;  
27         }  
28         return utfBytes;  
29     }  

PS:有點兒對不住原做者,找了不少代碼,一一測試,結果網頁都關閉了,若是有大神認領,我必定補充連接,並且深表感謝。

相關文章
相關標籤/搜索