1. 程式人生 > >Unicode 與 utf8 utf16 utf32的關系

Unicode 與 utf8 utf16 utf32的關系

基本 ati bsp body lin windows編程 空間 head dash

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的關系