《資訊話題》 Unicode與ISO10646(下)(作者:曾士熊) (續1510期) 三、UTF-16與UTF-8 ISO10646的編碼空間足以容納古今人類使用過的所有文字和符號, 但目前真正被使用的文字或符號,絕大多數都已編入BMP,它們的使 用頻率可能超過99%,甚至99.99%。換言之,就99%以上的使用者或 使用場合而言,16位元的Unicode已是足敷需求,32位元的ISO10646 正規編碼則顯得割雞用牛刀。32位元編碼不只要比16位元編碼佔用 多一倍的記憶或儲存空間,而且在網路傳輸和資訊處理上也需花費 比較長的時間。就經濟效益而言,將來電腦和網路選擇使用Unicode 的可能性,很明顯地要高於選擇使用32位元的ISO10646正規編碼。 問題是,在Unicode的世界裡,遇到必須使用646第1、第2字面甚至 更後方字面的字元時,怎麼辦?Unicode協會提出的解決方式稱為 UTF-16或代理法(surrogates)。 UTF為“a UCS(or Unicode) Transformation Format”的縮寫,UTF-16意即把原為32位元的 ISO10646字元碼轉換為2或多個16位元的Unicode。目前的作法是組 合兩個Unicode字元碼來代表一個ISO10646字元,如【圖二】所示, 所以又稱為代表法。兩個做為代表的Unicode,位於前方(左方) 者稱為高半字元,限定只能選用D800∼DBFFh當中之一,位於後方 (右方)者稱為低半字元,限制只可從DC00∼DFFFh當中選擇。高 低半字元的編碼位置各為1,024=4×256,因此UTF-16總計可提供 (4×256)×(4×256)=16×65536個編碼位置,亦即16個字面。 對BMP而言,當然無需使用UTF-16轉碼,所以UTF-16主要應用於 ISO10646的第1∼第14字面(因為第15字面為專用字面,WG2不予編 碼)。將ISO10646字元(編碼範圍0001-0000∼000E-FFFFh)以 UFT-16轉換成Unicode組合形式的規則,如【圖三】所示,圖中為了 方便對應16進制,特別將字元碼表現成每4個位元一組,中間以短槓 分隔。轉換方式不難,將原來的32位元ISO10646字元碼,從右往左 取出10個位元(即圖中的Y10∼Y1)前頭附加上特定的6個位元110111, 即成為低半字元。接著往左取出6個位元(即圖中的Y16∼Y11)做為 高半字元的最低6個位元,然後再往左取出4個位元(即圖中的Z4∼Z1, 相當於Y20∼Y17,其值可顯示第0∼第15字面),將其值減1,置於剛 才那6個位元的左方,最後在最前方附加上特定的6個位元110110,即 成為高半字元。以上所介紹的是UTF-16轉換的觀念,至於UTF-16的轉 換公式和還原公式,請詳見ISO10646標準或Unicode標準。 請特別注意,UTF-16係針對Unicode世界所設計的。也就是說,當 網際網路和大部分的電腦都已經採用Unicode了,UTF-16才可用來表 現ISO10646第1∼第14字面的字元碼。很不幸的事實並非如此,現在 是ASCII世界而非Unicode世界。當某一個Unicode離開溫室(某個以 Unicode為內碼的作業系統或應用程式)之後,馬上會被網路設備切 成兩個8位元的位元組,並嚴密檢查是否有任何位元組為C0控制碼, 至少數千個Unicoe將因此變得殘缺不全。為了能讓Unicode和ISO10646 字元碼能安然通行於ASCII世界,Unicode協會特別提出UTF-8以解決 問題。UTF-8意即把原為32位元的ISO10元碼或原為16位元的Unicode 轉換為多個8位元的位元組。 利用UTF-8轉碼規則可將一個Unicode或ISO10646字元碼轉換成1∼4 個位元組的編碼,如【圖四】所示。UTF-8的轉換規則很簡單:若原始 字元碼位於0000∼007Fh(或0000-0000∼0000-007Fh)的範圍內,則 直接截取最右8個位元即可,轉換結果其實就是ASCII碼。若原始字元 碼大於007Fh(或0000-007Fh),亦即超出ASCII範圍時,就必須轉換 成2∼4個位元組。UTF-8規定,以轉換後第1位元組起頭連續設為“1” 的標記位元的數目表示轉換成幾個位元組:110表示轉換結果為2個位 元組,1110表示3個位元組,而11110則表示4個位元組。至於跟隨在標 記位元之後設為0的位元,其在分隔標記位元和字元碼位元。第2∼第4 位元組起頭兩個位元被設為10當做識別,剩下的6個位元才做為字元碼 位元使用。總計,2位元組UTF-8碼剩下11個字元碼位元,可用以轉換 0080∼07FFh的原始字元碼。3位元組剩下16個字元碼位元,可用以轉換 0800∼FFFFh的原始字元碼。而4位元組則剩下21個字元碼位元,可用來 轉換0001-0000∼001F-FFFh(即ISO10646第1∼第31字面)的原始字 元碼。請注意,雖然4個位元組的UTF-8編碼可包容1∼3個位元組的碼, 3個位元組的編碼可包容1∼2個位元組的碼,以及2個位元組的編碼可包 容1個位元組的碼,但是UTF-8規定轉碼時必須選擇最短者。換言之, ASCCI區只能轉換成單一位元,0080∼07FFh的原始字元碼只能轉換成2 個位元組長度,依此類推。