Unicode的那些事兒

從記憶體到螢幕

unicode

觀念釐清

1. Unicode 和 ISO 10646 是字符集

2. UTF-8,UTF-16,UTF-32,UCS-2,UCS-4是編碼集

3. 字符集和編碼集是不一樣的東西

Unicode字符集 ( Unicode Code Points )

Unicode字符集廣義上有兩組

1. ISO 10646 (國際ISO組織)

編碼空間: 0x00000000 ~ 0X7FFFFFFF

2. Unicode (統一碼聯盟)

編碼空間: 0x00000000 ~ 0x0010FFFF

a. 0x00000000 ~ 0x0010FFFF以內兩者完全相同

b. 0x00000000 ~ 0X0000FFFF 定義了最常用的文字,稱為BMP
    (Basic Multilingual Plane, BMP)
    基本多語言平面

c. 0x00001000 ~ 0x0010FFFF
    稱為輔助平面
    為基本多語言平面16倍大

d. 0x00110000 ~ 0X7FFFFFFF
    不使用

1991年後兩個組織進行了統一
所以就不嚴格區分之

ISO標準的編碼空間較大
所以ISO承諾不會使用到0x0010FFFF以後的空間
0x00110000 ~ 0X7FFFFFFF 可以無視之

由於Unicode比較好記
所以我們通一稱為Unicode字符集

Unicode編碼集

Unicode並不強硬規定字符在電腦中的編碼
電腦系統可以根據需求採用不同編碼集

從編碼到Unicode稱為碼點對映
以下是著名的常用電腦編碼

1. UTF-8
    可變字組編碼,相容於ascii

2. UTF-16 UCS-2 (0xFFFF內所對映碼點相同)
    UTF-16 為 Unicode  的御用編碼,可變位元組
    UCS-2  為 ISO10646 的御用編碼,針對常用文字

3. UTF-32 UCS-4 (0x0010FFFF內所對映碼點相同)
    UTF-32 為 Unicode  的御用編碼
    UCS-4  為 ISO10646 的御用編碼
    已統一可視為相同

程式運作方法

1. 先將編碼轉成Unicode碼點
2. 再從Unicode碼點找到對映字符
3. 然後就可以將字符顯示在螢幕上

unicode

範例

以中文字”風”為例

1. UTF-8
    11101001 10100010 10101000 --> U+98A8 --> 風

2. UTF-16,UCS-2
    0x98A8 --> U+98A8 --> 風
    UTF-16編碼在0xFFFF以內和unicode是一對一對映

3. UTF-32,USC-4
    0x98A8 --> U+98A8 --> 風
    UTF-32編碼和unicode是一對一對映

各種編碼特性

UTF-32,UCS-4

1. 與碼點一對一對映,無需額外計算

2. 一個文字需要4byte的儲存空間,對拉丁語系國家而言很浪費

3. 傳輸和處理上需區分大序端或是小序端
   UTF-32 BE
   UTF-32 LE

UTF-16,UCS-2

1. 在0xFFFF內與碼點一對一對映,無需額外計算

2. UCS-2不支援超過0XFFFF以上的碼點

3. UTF-16支援超過0XFFFF以上的碼點,但需額外計算方法

4. 一個文字至少需要2byte以上儲存空間,對拉丁語系國家而言很浪費

5. 傳輸和處理上需區分大序端或是小序端
   UTF-16 BE
   UTF-16 LE

UTF-8

最常用的編碼
優點多,足以無視以上編碼
值得多花篇幅介紹

1. 相容於ascii編碼,拉丁語系和舊型軟體可以當成ascii碼點來處理
    單字節 000000 ~ 00007F 與 ascii 相同

2. 沒有大序端和小序端的問題,相容各種處理器和作業系統,傳輸和儲存方便

3. 可變位元組,所以需要額外的解碼運算

碼點對應規則

位元組 Unicode 碼點 UTF-8
1 byte 000000 ~ 00007F 0xxxxxxx
2 byte 000080 ~ 0007FF 110xxxxx 10xxxxxx
3 byte 000800 ~ 00FFFF 1110xxxx 10xxxxxx 10xxxxxx
4 byte 010000 ~ 10FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

如果你是某些不幸的碼農

一般高階的程式語言都有函式庫幫助碼農作編碼和解碼
但某些嵌入式系統業界的同伴們,或許沒那麼幸運
下圖可供參考


常用Unicode編碼比較表

編碼 UTF8 UTF-16 UCS-2 UTF-32, UCS-4
最少位元組 1 2 2 4
最多位元組 4 4 2 4
需處理endian問題 NO YES YES YES