2010年4月8日 星期四

Unicode, UTF-8, UTF-16, UCS-2 和一些程式語言的支援方式

讀 JavaScript 書時, 忽然想到 Unicode 支援問題, 就複習了一下相關知識。有錯還請指正。

什麼是 Unicode? 什麼是 UTF-X?

  • Unicode: 將全部語言用的字集統整成一張表。定義每個文字對應的數字, 像是 'a' 對應到 97,  '我' 對應到 25105。整張表含蓋的字集範圍介於 0 ~ 1114111 (0x10FFFF) 之間。
  • UTF-X: X bits Unicode Transformation Format。有了 Unicode 這張表, 再來就是定義怎麼儲存這張表。

UTF-8、UTF-16 和 UCS-2

  • UTF-32: 原封不動地把 Unicode 表裡的每個數字用 4 bytes 表示。相當浪費空間。
  • UTF-8: 可以想成某種資料壓縮方式。使得常用的 ASCII 字元仍用 1 byte 表示, 中文、日文、韓文等象型文字用 3 bytes 表示, 比原本各國自己用的表示方法多 1 byte (如日文的 Shift-JIS、簡體中文 GB 和繁體中文 Big5)。文字處理軟體 (如記事本、瀏覽器) 得「解壓縮」這種文字編碼方式, 還原回 Unicode 裡定義的數字, 才知道它是那個字。
  • UTF-16: 0 ~ 65535 的字用 2 bytes 表示, 之後的用 4 bytes 表示。
  • UCS-2: UTF-16 的子集, 只有 2 bytes 的字元組。
Wikipedia 的介紹很清楚地說明 UTF-8、UTF-16 如何動態地用 2 ~ 4 bytes 表示不同範圍的數字。設計的很巧妙, 值得一看。對程式設計師來說, 最棒的是沒有任何字元是其它字元的子字元, 於是字串比對演算法可以直接使用。像 Big5 設計不良, 有名的許功蓋問題, 實在是夢魘啊。

程式如何明白檔案使用的編碼方式?

有了這些編碼方式, 程式得先明白讀到的檔案用什麼編碼才能正常處理。像 HTML 的開頭:
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">”
和 Python 程式的開頭:
#-*- coding: utf-8 -*-
都是用來說明編碼方式。

程式語言支援 Unicode 的方式

不同的程式語言, 支援 Unicode 的程度不同, 方式也有差異。所謂「支援」的意思, 就是程式能正確地算出字串長度、索引到正確的字等。

Java 在 J2SE 5 前用 UCS-2, 從J2SE 開始用 UTF-16。JavaScript 似乎用 UCS-2 的樣子。而 Python 另外用了物件 unicode 來表示 Unicode (也是用 UTF-16)。在 Python 裡, 從 UTF-8 格式的檔案內讀入文字後, 文字的型別是 str, 若讀入的文字是中文的話, 它相當於 byte stream, 無法正確地操作字串, 得先轉為 unicode 才行。詳細的說明請見《All About Python and Unicode》, 講得超級清楚, 我之前就是讀這份弄懂的。

沒有留言:

張貼留言

在 Fedora 下裝 id-utils

Fedora 似乎因為執行檔撞名,而沒有提供 id-utils 的套件 ,但這是使用 gj 的必要套件,只好自己編。從官網抓好 tarball ,解開來編譯 (./configure && make)就是了。 但編譯後會遇到錯誤: ./stdio.h:10...