Unicode 與 utf8 utf16 utf32的關系
Unicode是計算機領域的一項行業標準,它對世界上絕大部分的文字的進行整理和統一編碼,Unicode的編碼空間可以劃分為17個平面(plane),每個平面包含2的16次方(65536)個碼位。17個平面的碼位可表示為從U+0000到U+10FFFF,共計1114112個碼位,第一個平面稱為基本多語言平面(Basic Multilingual Plane, BMP),或稱第零平面(Plane 0)。其他平面稱為輔助平面(Supplementary Planes)。基本多語言平面內,從U+D800到U+DFFF之間的碼位區段是永久保留不映射到Unicode字符,所以有效碼位為1112064個。
Unicode的編碼方式
unicode 只是一種字符碼表, 而在計算機中進行存儲時, 必須指定一種具體的存儲方式。常見的如utf8, utf16, utf32
比如,對於英文字符A , 在unicode中的值是65, 其在計算機中存儲時, 使用utf8 utf16 utf32等不同格式存儲時, 是完全不同的。
utf8存儲,在內存中就是0x41; utf16存儲,在內存中就是0x0041 ; utf32存儲,在內存中就是0x00000041
在windows編程中, 字符格式通常有多字節(ansic)與寬字符(unicode)之分。 很多時候,我們認為unicode就是用兩個字符來表示英文字母, 其實這是不準確的。 因為windows中,默認的unicode編碼方式就是utf16, 所以英文字符才是兩個字節。
UTF-8(8-bit Unicode Transformation Format)
UTF-8是一種變長編碼,對於一個Unicode的字符被編碼成1至4個字節。Unicode編碼與UTF-8的編碼的對應關系:
Unicode編碼 | UTF-8編碼(二進制) |
---|---|
U+0000 – U+007F | 0xxxxxxx |
U+0080 – U+07FF | 110xxxxx 10xxxxxx |
U+0800 – U+FFFF | 1110xxxx 10xxxxxx 10xxxxxx |
U+10000 – U+10FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
一個字節的uft8表示的unicode 碼範圍為(0 ~0x7F)
兩個字節長度的uft8 表示的unicode碼範圍為(0x80 ~ 0x07FF)
三個字節長度的uft8 表示的unicode碼範圍為(0x0800 ~ 0xFFFF)
四個字節長度的uft8 表示的unicode碼範圍為( 0x10000 ~ 0x10FFFF)
其中絕大部分的中文用三個字節編碼,部分中文用四個字節編碼,舉例如下:
Unicode | 字符 | UTF-8編碼 |
---|---|---|
U+0041 | A | 0x41 |
U+7834 | 破 | 0xE7 0xA0 0xB4 |
U+6653 | 曉 | 0xE6 0x99 0x93 |
U+2A6A5 | ??(四個龍) | 0xF0 0xAA 0x9A 0xA5 |
UTF-16(16-bit Unicode Transformation Format)
UTF-16也是一種變長編碼,對於一個Unicode字符被編碼成1至2個碼元,每個碼元為16位。
基本多語言平面(碼位範圍U+0000-U+FFFF)
在基本多語言平面內的碼位UTF-16編碼使用1個碼元且其值與Unicode是相等的(不需要轉換)。舉例如下
Unicode | 字符 | UTF-16(碼元) | UTF-16 LE(字節) | UTF-16 BE(字節) |
---|---|---|---|---|
U+0041 | A | 0x0041 | 0x41 0x00 | 0x00 0x41 |
U+7834 | 破 | 0x7834 | 0x34 0x78 | 0x78 0x34 |
U+6653 | 曉 | 0x6653 | 0x53 0x66 | 0x66 0x53 |
輔助平面(碼位範圍U+10000-U+10FFFF)
在輔助平面內的碼位在UTF-16中被編碼為一對16bit的碼元(即32bit,4字節),稱作代理對(surrogate pair)。組成代理對的兩個碼元前一個稱為前導代理(lead surrogates)範圍為0xD800-0xDBFF,後一個稱為後尾代理(trail surrogates)範圍為0xDC00-0xDFFF。
具體的轉換過程為
1 首先將unicode碼表 - 0x10000 , 這樣得到的輔助平面的碼表範圍為(U+0000 - U+FFFFF) ,總共最多20bit
2 將20bit ,分為high 10bit 與 low 10bit。 high 1bit | 0xD800 得到前導代理, low 10bit | 0xDC00 得到後尾代理
從這裏也可以理解為什麽 在基本多語言平面中, (U+D800 ~ U+DFFF ) 要作為保留字符了
舉例如下
Unicode | 字符 | UTF-16(碼元) | UTF-16 LE(字節) | UTF-16 BE(字節) |
---|---|---|---|---|
U+2A6A5 | ?? | 0xD869 0xDEA5 | 0x69 0xD8 0xA5 0xDE | 0xD8 0x69 0xDE 0xA5 |
UTF-32(32-bit Unicode Transformation Format)
UTF-32是一種定長編碼,使用1個32bit的碼元,其值與Unicode編碼值相等。舉例如下:
Unicode | 字符 | UTF-32(碼元) | UTF-32 LE(字節) | UTF-32 BE(字節) |
---|---|---|---|---|
U+0041 | A | 0x00000041 | 0x41 0x00 0x00 0x00 | 0x00 0x00 0x00 0x41 |
U+7834 | 破 | 0x00007834 | 0x34 0x78 0x00 0x00 | 0x00 0x00 0x78 0x34 |
U+6653 | 曉 | 0x00006653 | 0x53 0x66 0x00 0x00 | 0x00 0x00 0x66 0x53 |
U+2A6A5 | ?? | 0x0002A6A5 | 0xA5 0xA6 0x02 0x00 | 0x00 0x02 0xA6 0xA5 |
Unicode 與 utf8 utf16 utf32的關系