什麼是Unicode?
Unicode的學名是"Universal Multiple-Octet Coded Character Set",從名稱來看Unicode屬於一種字符集,字符集就是一張表,裏面收錄了大量的符號和文字,每個符號和文字有與之對應的標識。所謂的標識 ,就是對對這個字符集合裏的所有字符進行編碼,Unicode的編碼空間是從U+0000到U+10FFFF(16進制),整個編碼空間又被劃分爲17平面,每個平面包含(65535)個碼位,而第一個平面就已經包含了大多數國家常用的字符,所以第一個平面又稱爲“基本多語言平面”,其它平面稱爲輔助平面。除了Unicode,我們也會碰到UCS,UCS與Unicode雖然產生於不同的兩個組織,但是因爲編碼要統一,所以它們現在的內容基本保持一致,可以簡單的認爲,它們就是一個東西,而UCS-2和USC-4是從USC這個觀念下劃分出來的,可以簡單的理解爲USC-2對應Unicode中“基本多語言平面”的範圍,UCS-4只是在UCS-2前面加了0x0000,前面不變。USC-2用兩個字節對語言符號進行編碼,USC-4用4個字節對語言符號進行編碼。UTF
UTF的全稱是UCS Transformation Format,從名稱來看,UTF是用於數據存儲或傳遞的一種規範。跟Unicode不同,Unicode是一個
字符集合,它只規定了符號的二進制代碼,卻沒有規定這個二進制代碼應該如何存儲
UTF-16
UTF-16是Unicode字符編碼的一種實現方式。即把Unicode字符集的抽象碼位映射爲16位長的整數的序列,用於數據存儲或傳遞。在Unicode字符集U+0000-U+ffff的範圍中,也就是在第一個平面中,utf-16一律採用2個字節來存儲,在輔助平面中,utf-16採用兩個雙字節,也就是4個字節來存儲,所以整體來看utf-16是一種變長編碼。在Unicode字符集中從U+D800到U+DFFF之間的碼位區段永遠都不會被映射字符,因爲utf-16會利用這個區段的碼位來對輔助平面的字符碼位進行存儲(也就是把這個區段的值轉換成一串二進制數與輔助平面的符號相對應)。如果說utf-16利用這個區段的碼位來對輔助平面來存儲,在識別到兩個字符的時候,系統會去查Unicode字符表,發現找不到對應的字
符(因爲沒有映射字符),所以系統就會認爲採用的存儲方式是兩個雙字節作爲一個字符,然後再繼續往前讀取一個字節,最後系統會拿着這個數值去找Unicode字符集中輔助平面的字符。但是反過來講,如果這個區段被佔用了,這個區段的碼位有相對應的字符的話,utf-16還利用它對輔助平面來存儲的話,當讀取到2個字節的時候,系統
去查字符表,然後突然查到有對應的字符,那麼它就會認爲應該是2個字節作爲一個字符,然後它會按照“基本多語言平面”的編碼方式來解碼,所以utf-16對輔助平面的存儲也就無效了。
相對於UTF-8,UTF-16好處在於大部分字符都以固定長度的字節 (2字節) 儲存,但是它不兼容ASCII碼。
UTF-32
UTF-32一律採用4字節存儲,空間浪費比較大,用的也很少,不多提。
UTF-8
UTF-8最大的一個特點,就是它是一種變長的編碼方式。它可以使用1~4個字節表示一個符號,根據不同的符號而變化字節長度。UTF-8的編碼規則很簡單,只有二條:
對於單字節的符號,字節的第一位設爲0,後面7位爲這個符號的Unicode碼。因此對於英語字母,UTF-8編碼和ASCII碼是相同的,所以UTF-8兼容ASCII碼。
對於n字節的符號(n>1),第一個字節的前n位都設爲1,第n+1位設爲0,後面字節的前兩位一律設爲10。剩下的沒有提及的二進制位,全部爲這個符號的Unicode碼。
已知“嚴”的Unicode是4E25(100111000100101),根據上表,可以發現4E25處在第三行的範圍內(0000 0800-0000 FFFF),因此“嚴”的UTF-8編碼需要三個字節,即格式是“1110xxxx 10xxxxxx 10xxxxxx”。然後,從“嚴”的最後一個二進制位開始,依次從後向前填入格式中的x,多出的位補0。這樣就得到了,“嚴”的UTF-8編碼是“11100100 10111000 10100101”,轉換成十六進制就是E4B8A5。通過這個例子,可以看到“嚴”的Unicode碼是4E25,UTF-8編碼是E4B8A5,兩者是不一樣的。一個代表着在字符集中
的編號,另一個代表在計算機的存儲和傳遞方式。