字元編碼發展史5 — UTF-16和UTF-32

陌尘(MoChen)發表於2024-10-07

上一篇《字元編碼發展史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. 優缺點
  • 優點:
    1. 絕大部分的文字都可以用兩個位元組編碼,對於CJK文字是比較節省空間的;
    2. 文字處理比UTF-8方便得多。
  • 缺點:
    1. 儲存和傳輸需要考慮位元組序的問題;
    2. 不相容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,未來還會折騰更多東西,不死不休。

感謝大家的關注,期待與你一起成長。



【SunLogging】
字元編碼發展史5 — UTF-16和UTF-32
掃碼二維碼,關注微信公眾號,閱讀更多精彩內容

相關文章