UTF-8編碼規則解析
在將多個(UTF-8)位元組陣列轉換為字串的時候,可能會發生亂碼,這不是因為編碼問題。
UTF-8是一種變長位元組編碼方式。對於某一個字元的UTF-8編碼,如果只有一個位元組則其最高二進位制位為0;如果是多位元組,其第一個位元組從最高位開始,連續的二進位制位值為1的個數決定了其編碼的位數,其餘各位元組均以10開頭。UTF-8最多可用到6個位元組。
所以,如果一個字元編碼成3個位元組,但是一個位元組陣列的結尾可能只包含了其中兩個位元組,而後一個位元組陣列開頭包含了該字元編碼的最後一個位元組,那麼,如果兩個位元組陣列單獨解碼,就會發生亂碼。
要解決這個問題,要了解UTF-8的編碼規則,如下所示:
1位元組
2位元組110xxxxx
10xxxxxx
3位元組1110xxxx
10xxxxxx 10xxxxxx
4位元組11110xxx
10xxxxxx 10xxxxxx 10xxxxxx
5位元組111110xx
10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
6位元組1111110x
10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
知道了編碼規則,就知道如何處理這種情況了
當要對一個位元組陣列進行解碼時,要對這個位元組陣列最後幾個位元組進行判斷,如果是一個完整的字元,則可以進行解碼
否則,要將不完整的位元組截取出來,拼接到下一位元組陣列後進行解碼。
關於UTF-8佔幾個位元組的問題
佔2個位元組的:〇
佔3個位元組的:基本等同於GBK,含21000多個漢字
佔4個位元組的:中日韓超大字符集裡面的漢字,有5萬多個
一個utf8數字佔1個位元組
一個utf8英文字母佔1個位元組
在查詢 UTF-8 編碼資料時發現,很多的帖子說的 UTF-8 編碼裡,一個漢字佔用3個位元組,有的還做了個證明,大概是這樣的,建立一個沒有BOM的UTF-8編碼的文字檔案,裡面儲存了幾個漢字,然後檢視檔案的大小。我覺得這樣的證明沒有一點說服力,因為 UTF-8 是變長的,1-6個位元組,少量的漢字檢測是不能說明所有的漢字都是的。
後來我又查看了字元對映表-漢語,找到了正確的答案,少數是漢字每個佔用3個位元組,多數佔用4個位元組。
佔用3個位元組的範圍
- U+2E80 - U+2EF3 : 0xE2 0xBA 0x80 - 0xE2 0xBB 0xB3 共 115 個
- U+2F00 - U+2FD5 : 0xE2 0xBC 0x80 - 0xE2 0xBF 0x95 共 213 個
- U+3005 - U+3029 : 0xE3 0x80 0x85 - 0xE3 0x80 0xA9 共 36 個
- U+3038 - U+4DB5 : 0xE3 0x80 0xB8 - 0xE4 0xB6 0xB5 共 7549 個
- U+4E00 - U+FA6A : 0xE4 0xB8 0x80 - 0xEF 0xA9 0xAA 共 44138 個
- U+FA70 - U+FAD9 : 0xEF 0xA9 0xB0 - 0xEF 0xAB 0x99 共 105 個
合計: 52156 個
佔用4個位元組的範圍
- U+20000 - U+2FA1D : 0xF0 0xA0 0x80 0x80 - 0xF0 0xAF 0xA8 0x9D 共 64029 個
合計: 64029 個
如果想了解一下編碼史,可以看一下這篇部落格:http://blog.csdn.net/baixiaoshi/article/details/40786503
後續會貼出轉換的測試程式碼:
。
。
。
。
。