上一篇《字元編碼發展史4 — Unicode與UTF-8》我們講解了Unicode字符集與UTF-8編碼。本篇我們將繼續講解字元編碼的第三個發展階段中的UTF-16和UTF-32。
2.3. 第三個階段 國際化
2.3.2. Unicode的編碼方式
2.3.2.2. UTF-16
UTF-16也是一種變長編碼,對於一個Unicode字元被編碼成1至2個碼元,每個碼元為2個位元組(16位)。UTF-16編碼會有位元組序的問題,所以根據大小端又分為大端UTF-16(UTF-16 BE)和小端UTF-16(UTF-16 LE)。
1. 基本平面(碼點範圍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+03A9 |
Ω | 0x03A9 |
0xA9 0x03 |
0x03 0xA9 |
U+6653 |
曉 | 0x6653 |
0x53 0x66 |
0x66 0x53 |
2. 輔助平面(碼點範圍U+10000-U+10FFFF)
輔助平面的碼點在UTF-16中被編碼為一對雙位元組(16位)的碼元(即32位,4位元組),稱作代理對(surrogate pair
),編號範圍:0xD800~0xDFFF
,也就是前文提到的代理區的範圍。這也就是為什麼基本多語言平面會保留一塊代理區(0xD800~0xDFFF
)的碼點不定義任何字元的原因。
組成代理對的兩個碼元前一個稱為前導代理(lead surrogates
)範圍為0xD800-0xDBFF
,可表達1024(2^10)個碼元;後一個稱為後尾代理(trail surrogates
)範圍為0xDC00-0xDFFF
,可表達1024(2^10)個碼元。這樣兩個碼元組合在一起就可以表達 2^20
(2^10 * 2 ^ 10
)個編碼,正好和輔助平面的碼點範圍U+10000-U+10FFFF
對應。
UTF-16輔助平面代理對與Unicode的對應關係如下表。
- 第一列: 表示前導代理。
- 第一行: 表示後尾代理。
- 表格內容: 表示Unicode的碼點編號。
\ | 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(位元組) | UTF-16 BE(位元組) |
---|---|---|---|---|
U+2A6A5 | 𪚥 | 0xD869 0xDEA5 | 0x69 0xD8 0xA5 0xDE | 0xD8 0x69 0xDE 0xA5 |
3. 優缺點
- 優點:
- 絕大部分的文字都可以用兩個位元組編碼,對於CJK文字是比較節省空間的;
- 文字處理比UTF-8方便得多。
- 缺點:
- 儲存和傳輸需要考慮位元組序的問題;
- 不相容ASCII(準確的說是半相容,編碼值是一樣的,只是需要用兩個位元組來表示)。
2.3.2.3. UTF-32
1. UTF-32的編碼規則
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+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. 優缺點
- 優點:是編碼定長容易進行文字處理。
- 缺點:是浪費儲存空間及存在位元組序的問題。
2.3.2.4. UCS-2 與 UCS-4
前文提到:歷史上存在兩個獨立的嘗試創立單一字符集的組織,即 國際標準化組織(ISO
)和統一碼聯盟。統一碼聯盟除了收錄字符集外,還制定過兩套字元編碼方案:UCS2和UCS4。
1. UCS-2
UCS-2是一種定長編碼,編碼範圍為0x0000-0xFFFF,在基本多語言平面內與UTF-16是等價。UCS2沒有類似於UTF-16中代理對的概念,所以對於0xD869 0xDEA5會識別成兩個字元。所以它只能表示基本平面的字元,不能表示全部的Unicode字元。UCS2後來被UTF-16替代,現在基本已經被廢棄了。
2. UCS-4
UCS-4的編碼方式與UTF-32幾乎一樣,後來兩個組織統一標準後,就變成了UTF-32。不過ISO組織規定Unicode的編碼空間會限定在0x000000~0x10FFFF
之間,而UCS4的編碼範圍能到0~0xFFFFFFFF
。因此也可以認為:UTF-32 是 UCS-4 的一個子集。
未完待續…… 欲知後事如何,且看下回分解。
下回預告:字元編碼發展史6 — BOM位元組序標記。
歷史文章推薦:
字元編碼發展史4 — Unicode與UTF-8
字元編碼發展史3 — GB2312/Big5/GBK/GB18030
字元編碼發展史2 — ISO-8859-N
字元編碼發展史1 — ASCII和EASCII
大家好,我是陌塵。
IT從業10年+, 北漂過也深漂過,目前暫定居於杭州,未來不知還會飄向何方。
搞了8年C++,也幹過2年前端;用Python寫過書,也玩過一點PHP,未來還會折騰更多東西,不死不休。
感謝大家的關注,期待與你一起成長。