字符編碼發(fā)展史5 — UTF-16和UTF-32
上一篇《字符編碼發(fā)展史4 — Unicode與UTF-8》我們講解了Unicode字符集與UTF-8編碼。本篇我們將繼續(xù)講解字符編碼的第三個(gè)發(fā)展階段中的UTF-16和UTF-32。
2.3. 第三個(gè)階段 國(guó)際化
2.3.2. Unicode的編碼方式
2.3.2.2. UTF-16
UTF-16也是一種變長(zhǎng)編碼,對(duì)于一個(gè)Unicode字符被編碼成1至2個(gè)碼元,每個(gè)碼元為2個(gè)字節(jié)(16位)。UTF-16編碼會(huì)有字節(jié)序的問題,所以根據(jù)大小端又分為大端UTF-16(UTF-16 BE)和小端UTF-16(UTF-16 LE)。
1. 基本平面(碼點(diǎn)范圍U+0000-U+FFFF)
在基本多語言平面內(nèi)的碼位UTF-16編碼使用1個(gè)碼元且其值與Unicode是相等的(不需要轉(zhuǎn)換)。舉例如下:
| Unicode | 字符 | UTF-16(碼元) | UTF-16 LE(字節(jié)) | UTF-16 BE(字節(jié)) |
|---|---|---|---|---|
U+0041 |
A | 0x0041 |
0x41 0x00 |
0x00 0x41 |
U+03A9 |
Ω | 0x03A9 |
0xA9 0x03 |
0x03 0xA9 |
U+6653 |
曉 | 0x6653 |
0x53 0x66 |
0x66 0x53 |
2. 輔助平面(碼點(diǎn)范圍U+10000-U+10FFFF)
輔助平面的碼點(diǎn)在UTF-16中被編碼為一對(duì)雙字節(jié)(16位)的碼元(即32位,4字節(jié)),稱作代理對(duì)(surrogate pair),編號(hào)范圍:0xD800~0xDFFF,也就是前文提到的代理區(qū)的范圍。這也就是為什么基本多語言平面會(huì)保留一塊代理區(qū)(0xD800~0xDFFF)的碼點(diǎn)不定義任何字符的原因。
組成代理對(duì)的兩個(gè)碼元前一個(gè)稱為前導(dǎo)代理(lead surrogates)范圍為0xD800-0xDBFF,可表達(dá)1024(2^10)個(gè)碼元;后一個(gè)稱為后尾代理(trail surrogates)范圍為0xDC00-0xDFFF,可表達(dá)1024(2^10)個(gè)碼元。這樣兩個(gè)碼元組合在一起就可以表達(dá) 2^20(2^10 * 2 ^ 10)個(gè)編碼,正好和輔助平面的碼點(diǎn)范圍U+10000-U+10FFFF對(duì)應(yīng)。
UTF-16輔助平面代理對(duì)與Unicode的對(duì)應(yīng)關(guān)系如下表。
- 第一列: 表示前導(dǎo)代理。
- 第一行: 表示后尾代理。
- 表格內(nèi)容: 表示Unicode的碼點(diǎn)編號(hào)。
| \ | 0xDC00 | 0xDC01 | … | 0xDFFF |
|---|---|---|---|---|
| 0xD800 | U+10000 | U+10001 | … | U+103FF |
| 0xD801 | U+10400 | U+10401 | … | U+107FF |
| ? | ? | ? | ? | ? |
| 0xDBFF | U+10FC00 | U+10FC01 | … | U+10FFFF |
舉例如下
| Unicode | 字符 | UTF-16(碼元) | UTF-16 LE(字節(jié)) | UTF-16 BE(字節(jié)) |
|---|---|---|---|---|
| U+2A6A5 | ?? | 0xD869 0xDEA5 | 0x69 0xD8 0xA5 0xDE | 0xD8 0x69 0xDE 0xA5 |
3. 優(yōu)缺點(diǎn)
- 優(yōu)點(diǎn):
- 絕大部分的文字都可以用兩個(gè)字節(jié)編碼,對(duì)于CJK文字是比較節(jié)省空間的;
- 文本處理比UTF-8方便得多。
- 缺點(diǎn):
- 存儲(chǔ)和傳輸需要考慮字節(jié)序的問題;
- 不兼容ASCII(準(zhǔn)確的說是半兼容,編碼值是一樣的,只是需要用兩個(gè)字節(jié)來表示)。
2.3.2.3. UTF-32
1. UTF-32的編碼規(guī)則
UTF-32是一種定長(zhǎng)編碼,使用1個(gè)32bit的碼元,其值與Unicode編碼值相等。舉例如下:
| Unicode | 字符 | UTF-32(碼元) | UTF-32 LE(字節(jié)) | UTF-32 BE(字節(jié)) |
|---|---|---|---|---|
U+0041 |
A | 0x00000041 |
0x41 0x00 0x00 0x00 |
0x00 0x00 0x00 0x41 |
U+03A9 |
Ω | 0x000003A9 |
0xA9 0x03 0x00 0x00 |
0x00 0x00 0x03 0xA9 |
U+6653 |
曉 | 0x00006653 |
0x53 0x66 0x00 0x00 |
0x00 0x00 0x66 0x53 |
U+2A6A5 |
?? | 0x0002A6A5 |
0xA5 0xA6 0x02 0x00 |
0x00 0x02 0xA6 0xA5 |
UTF-32同樣有大小端的問題。
2. 優(yōu)缺點(diǎn)
- 優(yōu)點(diǎn):是編碼定長(zhǎng)容易進(jìn)行文本處理。
- 缺點(diǎn):是浪費(fèi)存儲(chǔ)空間及存在字節(jié)序的問題。
2.3.2.4. UCS-2 與 UCS-4
前文提到:歷史上存在兩個(gè)獨(dú)立的嘗試創(chuàng)立單一字符集的組織,即 國(guó)際標(biāo)準(zhǔn)化組織(ISO)和統(tǒng)一碼聯(lián)盟。統(tǒng)一碼聯(lián)盟除了收錄字符集外,還制定過兩套字符編碼方案:UCS2和UCS4。
1. UCS-2
UCS-2是一種定長(zhǎng)編碼,編碼范圍為0x0000-0xFFFF,在基本多語言平面內(nèi)與UTF-16是等價(jià)。UCS2沒有類似于UTF-16中代理對(duì)的概念,所以對(duì)于0xD869 0xDEA5會(huì)識(shí)別成兩個(gè)字符。所以它只能表示基本平面的字符,不能表示全部的Unicode字符。UCS2后來被UTF-16替代,現(xiàn)在基本已經(jīng)被廢棄了。
2. UCS-4
UCS-4的編碼方式與UTF-32幾乎一樣,后來兩個(gè)組織統(tǒng)一標(biāo)準(zhǔn)后,就變成了UTF-32。不過ISO組織規(guī)定Unicode的編碼空間會(huì)限定在0x000000~0x10FFFF之間,而UCS4的編碼范圍能到0~0xFFFFFFFF。因此也可以認(rèn)為:UTF-32 是 UCS-4 的一個(gè)子集。
未完待續(xù)…… 欲知后事如何,且看下回分解。
下回預(yù)告:字符編碼發(fā)展史6 — BOM字節(jié)序標(biāo)記。
歷史文章推薦:
大家好,我是陌塵。
IT從業(yè)10年+, 北漂過也深漂過,目前暫定居于杭州,未來不知還會(huì)飄向何方。
搞了8年C++,也干過2年前端;用Python寫過書,也玩過一點(diǎn)PHP,未來還會(huì)折騰更多東西,不死不休。
感謝大家的關(guān)注,期待與你一起成長(zhǎng)。

浙公網(wǎng)安備 33010602011771號(hào)