1. 程式人生 > >UTF-8編碼規則解析

UTF-8編碼規則解析

在將多個(UTF-8)位元組陣列轉換為字串的時候,可能會發生亂碼,這不是因為編碼問題。

UTF-8是一種變長位元組編碼方式。對於某一個字元的UTF-8編碼,如果只有一個位元組則其最高二進位制位為0;如果是多位元組,其第一個位元組從最高位開始,連續的二進位制位值為1的個數決定了其編碼的位數,其餘各位元組均以10開頭。UTF-8最多可用到6個位元組。

所以,如果一個字元編碼成3個位元組,但是一個位元組陣列的結尾可能只包含了其中兩個位元組,而後一個位元組陣列開頭包含了該字元編碼的最後一個位元組,那麼,如果兩個位元組陣列單獨解碼,就會發生亂碼。

要解決這個問題,要了解UTF-8的編碼規則,如下所示:

1位元組

0xxxxxxx 
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個位元組的範圍

  1. U+2E80 - U+2EF3 : 0xE2 0xBA 0x80 - 0xE2 0xBB 0xB3      共 115 個  
  2. U+2F00 - U+2FD5 : 0xE2 0xBC 0x80 - 0xE2 0xBF 0x95      共 213 個  
  3. U+3005 - U+3029 : 0xE3 0x80 0x85 - 0xE3 0x80 0xA9      共 36 個  
  4. U+3038 - U+4DB5 : 0xE3 0x80 0xB8 - 0xE4 0xB6 0xB5      共 7549 個  
  5. U+4E00 - U+FA6A : 0xE4 0xB8 0x80 - 0xEF 0xA9 0xAA      共 44138 個  
  6. U+FA70 - U+FAD9 : 0xEF 0xA9 0xB0 - 0xEF 0xAB 0x99      共 105 個  

合計: 52156 個

佔用4個位元組的範圍

  1. U+20000 - U+2FA1D : 0xF0 0xA0 0x80 0x80 - 0xF0 0xAF 0xA8 0x9D      共 64029 個  

合計: 64029 個


如果想了解一下編碼史,可以看一下這篇部落格:http://blog.csdn.net/baixiaoshi/article/details/40786503

後續會貼出轉換的測試程式碼: