ANSI C讀書筆記系列之字符集篇----第三章 字符集和編碼(II Unicode編碼)

前面說過,每個國家都有一套自己的編碼系統,每個國家的電腦就得裝上支持自己那套編碼的字符翻譯系統.但你要顯示其他國家的語言那估計就是亂碼了,尤其在現今網絡時代.大凡這時,歷史總會有新的標準來解決這個問題.而且同時做這工作的有兩羣人.

通用多八位編碼字符集(Universal Multiple-Octet Coded Character Set)簡稱UCS,是ISO組織從1984年起就開始研究制定一個全新的標準,標準編號爲:ISO 10646,這一標準爲世界各種主要語言的字符及附加符號,編制統一的內碼.

統一碼(Unicode)是Universal Code的縮寫,是由另一個叫"Unicode學術學會"(The Unicode Consortium)的機構制定的字符編碼系統.當然,他們工作的目的和上面那羣人是一致的.

在1991年,Unicode學術學會與ISO國際標準化組織決定共同制訂一套適用於多種語言文本的通用編碼標準.Unicode與ISO 10646國際編碼標準於1992年1月正式合作發展一套通用編碼標準.自此,兩個組織便一直緊密合作,同步發展Unicode及ISO 10646國際編碼標準.

下面的分析可以讓你瞭解到UCS與UNICODE的聯繫和區別了.

UCS的結構是一個四維的編碼空間,每一維由一個字節(八位二進制位)組成,範圍是00到FF.於是,UCS總體上分爲128個羣組(Group 00-7F),每一羣組由256個平面(Plane 00-FF)組成,每一平面有256行(Row 00-FF),每一行256個編碼位(Cell 00-FF).所以,每一平面包括65,536個字符位(Character Position 0000-FFFF).整個編碼字符集的每個字符都由4個字節,按“組-面-行-列”的順序表示.所以UCS的可編碼空間爲:128 × 256 × 256 × 256.UCS將其第一個平面(00羣組中的00平面)稱作基本多語種平面(Basic Multilingual Plane,BMP).

在UCS中,目前只有00組是重要的,Unicode學術學會斷言,在可以預見的將來,甚至不可能用完00組中的前17個平面(00平面到10平面).因此,Unicode只定義了ISO 10646的第00組的前17個平面.事實上,目前絕大多數字符,都分配在第00平面BMP中.

UCS有兩種方式來表示一個字符編碼:四字節正規形式(UCS-4,Four-octet canonical form)和雙字節基本平面形式(UCS-2,Two-octet BMP form).UCS-4用4個字節來表示一個字符.第一個字節表示組,第二表示平面,第三表示行,第四表示單元號或列.

當系統只使用BMP的字符碼時,可以省略羣組和平面中的八位,將字符碼由32個位縮短爲16個位,標記爲UCS-2.

Unicode和UCS-2同樣採用16位編碼.所以一般可以把Unicode和UCS-2看作是同一樣東西.

看到這,我們肯定有問題:2字節很容易用完吧?而且開始Unicode不是說17個平面才能保證可預見的未來足夠用麼?確實如此,代理對(Surrogate Pair)的設計在這種背景下應運而生.

UCS-2在BMP中開闢了一個特殊的區間(D800 - DFFF)-- 代理區,並平分成兩個區,分別稱爲高半代理區(High-half Zone,D800 - DBFF)和低半代理區(Low-half Zone,DC00 - DFFF),各有1024個碼位.使用時,從高低兩個代理區中各取一個編碼組成一個四字節的代理,來表示一個在BMP以外平面上的編碼字符位.這樣一來,總共可以多表示1024×1024個字符,映射到00羣組中的01到10平面(共16個平面).

UCS只是一個字形和內碼上的標準,並沒有定義實際在計算機上存取的方法,即Unicode 的實現方式.應該說,對Unicode編碼的實現方式根據不同平臺可以有不同實現.Unicode的實現方式稱爲Unicode轉換格式(Unicode Translation Format,簡稱爲 UTF).

UTF-16:用定長16位(2字節)來表示的UCS-2或Unicode轉換格式.它將Unicode的編碼值變成2字節表示.UTF-16利用代理對來訪問BMP之外的字符編碼.

UTF-8: 8bit變長編碼.對UCS-2,由1字節至3字節構成.如果UCS-2使用了代理對,則UTF-8最長可到4字節,對UCS-4,由1字節至6字節構成.

UTF-8的編碼規則有二條:

1)對於單字節的符號,字節的第一位設爲0,後面7位爲這個符號的unicode碼.因此對於英語字母,UTF-8編碼和ASCII碼是相同的.

2)對於n字節的符號(n>1),第一個字節的前n位都設爲1,第n+1位設爲0,後面字節的前兩位一律設爲10.剩下的沒有提及的二進制位,全部爲這個符號的unicode碼.可參考下表:

   Unicode符號範圍               |      UTF-8編碼方式
        (十六進制)                    |        (二進制)
--------------------+---------------------------------------------
0000 0000----0000 007F   |    0xxxxxxx
0000 0080----0000 07FF   |    110xxxxx 10xxxxxx
0000 0800----0000 FFFF   |    1110xxxx 10xxxxxx 10xxxxxx
0001 0000----0010 FFFF   |    11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

 

下面,還是以漢字"嚴"爲例,演示如何實現UTF-8編碼.

已知"嚴"的unicode是4E25(100111000100101),根據上表,可以發現4E25處在第三行的範圍內(0000 0800-0000 FFFF),因此"嚴"的UTF-8編碼需要三個字節,即格式是“1110xxxx 10xxxxxx 10xxxxxx”.然後,從"嚴"的最後一個二進制位開始,依次從後向前填入格式中的x,多出的位補0.這樣就得到了"嚴"的UTF-8編碼是"11100100 10111000 10100101",轉換成十六進制就是E4B8A5.

介紹到這,Unicode編碼歷史基本上都介紹到了,這裏面同樣還有一個字節序問題.後面繼續介紹.

 




 

 

 

 

 

 

 

 

發佈了38 篇原創文章 · 獲贊 10 · 訪問量 17萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章