- Unicode 定義中, 一個字碼單位稱為一個 code point. 每 65,535 個 code points 組成一個 plane. 而目前總共定義有 17 個 planes. 最常用的字碼都集中在第一個 plane 中 (plane #0), 該 plane 又稱為 BMP (Basic Multilingual Plane).
- Windows 中的 wchar_t 長度是 16 bits, 使用 UTF-16 編碼. 16 bits 只有辦法涵蓋一個 plane 的字碼量, 因此正常來說就是映射到 BMP 的字碼. 罕見情況下需要使用其它 plane 中的字碼時, 就用連續的兩個 wchar_t 來表示一個 Unicode code point (稱為 Surrogate Pair, 代理對). 所以不要認為 Windows 系統上所有的 wchar_t 字串 raw bytes 長度除以 2 就是字串長. 有機會陰溝裡翻船.
- Unix 中的 wchar_t 長度是 32 bits, 使用 UTF-32 編碼. 因為 32 bits 已經可以涵蓋所有 planes 所有 code points. 所以 Unix 上一個 wchar_t 一定就對應到一個 Unicode code point.
- UTF-8 轉換理論上要能函蓋所有 code points, 但實際上大多數的 UTF-8 轉換實作都只針對 BMP 中的 code points. 意即每次讀入一個 UTF-16 2bytes 轉換為 UTF-8 1~3bytes, 且不考慮 Surrogate Pair, 因此 Surrogate Pair 的兩個 wchar_t 會被錯誤地當成兩個獨立的 UTF-16 字碼進行轉換. 現今漸漸改用 CESU-8 這個詞來稱呼這種較簡略且非正規的轉換法. CESU 為 Compatibility Encoding Scheme for UTF-16 的縮寫.
- Modified UTF-8 原理其實跟 CESU-8 是幾乎相同的 (所以正確來說, 應該叫 Modified CESU-8), 只差在 UTF-16 中的 NULL (即 0x0000) 並不轉換為 (0x00), 而是 (0xC080) 的雙字節, 以避免該 (0x00) 被當成字串結尾.
- 包含 Orcale, Java, Dalvik, Tcl, 等等重量級的軟體專案, 其中號稱的 UTF-8 轉換, 其實都只有達到 CESU-8 或 Modified UTF-8 的程度.
References:
- http://en.wikipedia.org/wiki/Unicode
- http://en.wikipedia.org/wiki/UTF-8
- http://en.wikipedia.org/wiki/CESU-8
沒有留言:
張貼留言