Unicode編碼方案概述

1.
前面講過,隨著計(jì)算機(jī)發(fā)展到世界各地,于是各個(gè)國家和地區(qū)各自為政,搞出了很多既兼容ASCII但又互相不兼容的各種編碼方案。這樣一來同一個(gè)二進(jìn)制編碼就有可能被解釋成不同的字符,導(dǎo)致不同的字符集在交換數(shù)據(jù)時(shí)帶來極大的不便。
比如大陸和臺灣是只相隔150海里、使用著同一種語言的兄弟地區(qū),也分別采用了不同的DBCS雙字節(jié)字符集編碼方案。
以前大陸地區(qū)必須裝上類似于“UCDOS希望漢字系統(tǒng)”這樣的中文處理系統(tǒng)專門來處理簡體漢字的顯示、輸入問題。
而臺灣地區(qū)由于采用BIG5編碼方案(統(tǒng)一繁體字編碼,俗稱大五碼,使用2個(gè)字節(jié)表示繁體漢字),則必須安裝類似于“ET倚天漢字系統(tǒng)”這樣的繁體中文處理系統(tǒng)才可以正確顯示、輸入繁體漢字。
因此,要想打開一個(gè)文本文件,就必須首先知道它所采用的編碼方案,否則用錯(cuò)誤的編碼方案進(jìn)行解碼,就會(huì)出現(xiàn)亂碼。為什么電子郵件常常出現(xiàn)亂碼?就是因?yàn)榘l(fā)信人和收信人使用的編碼方案不一樣。
2.
想象一下,如果有一種統(tǒng)一的編碼方案,將世界上所有語言字符都納入其中,每一個(gè)字符都給予一個(gè)全球獨(dú)一無二的編碼,那么亂碼問題就會(huì)消失。于是,全球所有國家和民族使用的所有語言字符的統(tǒng)一編碼方案誕生了。
最初,由多語言軟件制造商組成了統(tǒng)一碼聯(lián)盟(The Unicode Consortium),然后于1991年發(fā)布了The Unicode Standard(統(tǒng)一碼標(biāo)準(zhǔn)),定義了一個(gè)全球統(tǒng)一的通用字符集,習(xí)慣簡稱為Unicode字符集(Unicode常被稱為統(tǒng)一碼、萬國碼、單一碼,嚴(yán)格來說,這種稱呼不夠嚴(yán)謹(jǐn)或不夠準(zhǔn)確,因?yàn)閁nicode字符集只是一個(gè)編號字符集,其字符編號尚未經(jīng)過字符編碼方式CEF和字符編碼模式CES進(jìn)行編碼)。
接著,ISO及IEC也于1993年聯(lián)合發(fā)布了稱之為Universal Multiple-Octet Coded Character Set(通用多八位組編號字符集,習(xí)慣翻譯為“通用多八位編碼字符集”)、簡稱為UCS(Universal Character Set通用字符集)、標(biāo)準(zhǔn)號為ISO/IEC 10646-1的全球統(tǒng)一的通用字符集。
后來,統(tǒng)一碼聯(lián)盟與ISO/IEC雙方都意識到世界上沒有必要存在兩套全球統(tǒng)一的通用字符集,于是進(jìn)行整合,并為創(chuàng)立一個(gè)單一的全球統(tǒng)一的通用字符集而協(xié)同工作。到Unicode 2.0時(shí),Unicode字符集和UCS字符集(ISO/IEC 10646-1)基本保持了一致。
雖然現(xiàn)在兩個(gè)項(xiàng)目仍都存在,并獨(dú)立地公布各自的標(biāo)準(zhǔn),但統(tǒng)一碼聯(lián)盟和ISO/IEC都同意保持兩者的通用字符集相互兼容,并共同調(diào)整未來的任何擴(kuò)展。
目前,Unicode的知名度要比UCS知名度大得多,已成了全球統(tǒng)一的通用字符集或編碼方案的代名詞。并且在實(shí)踐中,Unicode也要比UCS應(yīng)用得更為廣泛得多。

3.
Unicode字符集的目標(biāo)是涵蓋目前人類使用的所有字符,并為每個(gè)字符分配唯一的字符編號(即碼點(diǎn)編號、碼點(diǎn)值),一一對應(yīng)于編號空間(Code Space代碼空間、碼空間、碼點(diǎn)空間)里的碼點(diǎn)(Code Point代碼點(diǎn))。
Unicode字符集將所有字符按照使用上的頻繁度劃分為17個(gè)平面(Plane層面),每個(gè)平面上的編號空間有2^16=65536個(gè)碼點(diǎn)。
(笨笨阿林原創(chuàng)文章,轉(zhuǎn)載請注明出處)
4.
其中第0個(gè)平面BMP(Basic Multilingual Plane基本多語言平面、基本多文種平面、基本平面、平面0),基本涵蓋了當(dāng)今世界上正在使用中的常用字符。我們平常用到的Unicode字符,一般都是位于BMP平面上的。
BMP平面以外其他的增補(bǔ)平面(也稱為輔助平面)要么用來表示一些非常特殊的字符(比如不常用的象形文字、遠(yuǎn)古時(shí)期的文字等),且多半只有專家在歷史和科學(xué)領(lǐng)域里才會(huì)用到它們;要么被留作擴(kuò)展之用。目前Unicode字符集中尚有大量編號空間未被使用。
另外,BMP平面有一個(gè)專用區(qū)(Private Use Zone):0xE000~0xF8FF(十進(jìn)制57344~63743),共6400個(gè)碼點(diǎn),被保留為專用(私用),因而永遠(yuǎn)不會(huì)被分配給任何字符;還有一個(gè)被稱為代理區(qū)(Surrogate Zone)的特殊區(qū)域:0xD800-0xDFFF(十進(jìn)制55296~57343),共2048個(gè)碼點(diǎn),目的是用基本平面BMP中的兩個(gè)碼點(diǎn)“代理”表示BMP以外的其他增補(bǔ)平面的字符(解釋詳見后文)。

5.
Unicode字符集的字符編碼方式一開始規(guī)定用兩個(gè)字節(jié)(即16位)來統(tǒng)一表示所有的字符(即UTF-16編碼方式,UTF-16編碼方式要早于UTF-8編碼方式、UTF-32編碼方式出現(xiàn),詳見后文)。
對于ASCII字符,與前面介紹的ANSI編碼一樣,Unicode也保持其原編碼不變(準(zhǔn)確地說,應(yīng)該是保持其“編號不變”,因?yàn)樵趥鹘y(tǒng)字符編碼模型中,編號與編碼不作區(qū)分,說“編碼不變”也勉強(qiáng)可以),只是在UTF-16字符編碼方式中將其長度由原來的8位擴(kuò)展為16位(注意,這里的字符編碼方式CEF還只是邏輯意義上的碼元序列,不是字符編碼模式CES——物理意義上的字節(jié)序列),而其他文化和語言的字符則全部重新統(tǒng)一編碼。
由于ASCII字符只需要用到UTF-16的16位編碼中的低8位,所以其高8位永遠(yuǎn)是0(實(shí)際上也只用到了低8位中的低7位,因此準(zhǔn)確地說其高9位永遠(yuǎn)是0)。
6.
在Unicode標(biāo)準(zhǔn)最初推出的UTF-16字符編碼方式中,無論是半角的英文字母,還是全角的漢字,它們都表示統(tǒng)一的“一個(gè)字符”,同時(shí)其編碼也都是統(tǒng)一的“兩個(gè)字節(jié)”(也因此UTF-16屬于雙字節(jié)碼元編碼方式,而Unicode標(biāo)準(zhǔn)在UTF-16字符編碼方式之后所推出的UTF-8字符編碼方式則屬于單字節(jié)碼元編碼方式,兩者之間的關(guān)系與區(qū)別詳見后文)。
請注意這里的“字符”和“字節(jié)”兩個(gè)術(shù)語意義上的不同:“字節(jié)”是一個(gè)與計(jì)算機(jī)相關(guān)的物理意義上的8位存貯單元,而“字符”則是一個(gè)與文化相關(guān)的邏輯意義上的文字符號。
7.
在Unicode標(biāo)準(zhǔn)推出之前,那些做多語言國際軟件的公司遇上過很大麻煩。他們?yōu)榱嗽诓煌膰忆N售同一套軟件,就不得不特別注意字符編碼的問題。不僅要處處小心不要搞錯(cuò),還要把軟件中的文字在不同的字符編碼中轉(zhuǎn)換來轉(zhuǎn)換去,而Unicode標(biāo)準(zhǔn)的出現(xiàn),提供了一個(gè)很好的一攬子解決方案。
于是從Windows NT開始,微軟趁機(jī)把操作系統(tǒng)改了一遍,把所有的核心代碼都改成了采用Unicode標(biāo)準(zhǔn)的版本(實(shí)際使用的就是Unicode標(biāo)準(zhǔn)的UTF-16字符編碼方式CEF所對應(yīng)的UTF-16字符編碼模式CES)。
從Windows NT開始,Windows系統(tǒng)終于無需要加裝各種本土語言系統(tǒng)(比如“UCDOS希望漢字系統(tǒng)”之類的),就可以直接顯示全世界上所有的字符了。當(dāng)然,為了保持兼容性,對于之前的ANSI編碼方案,Windows仍然是必須支持的。
(笨笨阿林原創(chuàng)文章,轉(zhuǎn)載請注明出處)
8.
Unicode在剛開始制訂UTF-16字符編碼時(shí),并沒有考慮與任何一種現(xiàn)有的字符編碼保持完全兼容(與ASCII也只能算是間接兼容或者說半兼容,畢竟ASCII字符的UTF-16編碼也同樣是16位的),比如GBK與Unicode在漢字的編碼上完全是不一樣的,沒有任何一種簡單的算術(shù)方法可以將文本內(nèi)容在UTF-16編碼和GBK編碼之間進(jìn)行直接轉(zhuǎn)換,要轉(zhuǎn)換的話只能通過查表這樣低效率的笨辦法一個(gè)字符對應(yīng)一個(gè)字符地來進(jìn)行。
即便是ASCII字符,也屬于不完全兼容,因?yàn)閁TF-16也是用兩個(gè)字節(jié)來表示的,雖然低7位與ASCII保持了一致,其余高位的9位均只是占位的0,但畢竟還是使用了16位共兩個(gè)字節(jié)編碼,不同于ASCII碼的單字節(jié)編碼。正是鑒于此(當(dāng)然除此之外還有其他原因),于是后來又設(shè)計(jì)了UTF-8字符編碼方式,則保持了跟ASCII碼的完全兼容。
9.
從字符集的角度上來講,Unicode字符集不同于ASCII這樣不能再增加字符的封閉字符集,而是一個(gè)開放的字符集,是可以不斷增加字符的。因此Unicode字符集也在不斷發(fā)展(比如隨著互聯(lián)網(wǎng)即時(shí)聊天工具的發(fā)展而流行起來的很多Emoji表情符就不斷地被增加到了Unicode字符集中),理論上支持的字符數(shù)量是沒有上限的,未來還可再擴(kuò)展。
(注意,很多文章中,有時(shí)候稱字符集,有時(shí)候稱字符編碼方案,大致上來講,字符集與字符編碼方案經(jīng)常被視為同義詞,尤其是在傳統(tǒng)字符編碼模型中。但若深究起來的話,在現(xiàn)代字符編碼模型中,由于字符集實(shí)際上為編號字符集的簡稱,因此字符編碼方案實(shí)際上涵蓋了字符集。具體可參看前面對于現(xiàn)代字符編碼模型的解釋。)

10.
另外,與Unicode字符集基本保持兼容的ISO/IEC UCS字符集分為UCS-2(2-byte Universal Character Set)和UCS-4(4-byte Universal Character Set)兩部分,分別以2字節(jié)和4字節(jié)表示字符編號(即碼點(diǎn)編號)。
(注意,UCS-2和UCS-4只是表示字符編號的字節(jié)數(shù)不同,與字符編碼方式CEF中的2字節(jié)與4字節(jié)沒有關(guān)系,也因此不能分別等同于Unicode編碼方案中的UTF-16和UTF-32字符編碼方式CEF,有不少文章中稱兩者等同,這是完全錯(cuò)誤的。事實(shí)上,由UCS-2和UCS-4所組成的UCS字符集跟Unicode字符集一樣,都可分別采用UTF-8、UTF-16和UTF-32字符編碼方式CEF對字符編號進(jìn)行編碼。)
其中,UCS-2又被稱為基本多語言平面BMP(Basic Multilingual Plane),與Unicode的基本多語言平面BMP保持了一致;而UCS-4格式用四個(gè)字節(jié)中的31位來表示一個(gè)字符的碼點(diǎn)編號(即字符編號),這樣可表示21億個(gè)不同的字符(2^31=2147483648;最高位為0,另有用途)。
不過,實(shí)踐中UCS字符集應(yīng)用得不多,基本以Unicode字符集為主,因此不作詳細(xì)介紹。
11.
Unicode字符集不僅給每個(gè)字符根據(jù)其所在的碼點(diǎn)分配了一個(gè)唯一的碼點(diǎn)值(即碼點(diǎn)編號,不嚴(yán)格地來講,也勉強(qiáng)可認(rèn)為是字符編號,注意不要跟UTF-16、UTF-8等字符編號的編碼方式混淆了概念),而且賦予了一個(gè)正式的名稱:在表示一個(gè)Unicode編號(或UCS編號)的十六進(jìn)制數(shù)的前面加上“U+”。
比如,U+0041表示英語大寫字母A,U+4E25表示漢字“嚴(yán)”。具體的字符對應(yīng)表,可以查詢unicode.org,漢字也可查詢專門的中日韓漢字Unicode編碼表。
Unicode字符集中的U+0000~U+007F(即十進(jìn)制的0~127)與ASCII字符集(即ISO/IEC 646標(biāo)準(zhǔn))是一致的,U+0000~U+00FF(即十進(jìn)制的0~255)與ISO/IEC 8859-1標(biāo)準(zhǔn)(Latin-1字符集)也是一致的。
(笨笨阿林原創(chuàng)文章,轉(zhuǎn)載請注明出處)
【預(yù)告:下一篇將重點(diǎn)講解另無數(shù)人頭大的字節(jié)序(大端序、小端序),敬請關(guān)注!】