天天看點

統一碼Unicode(UTF-8 UTF-16 GB18030等)的了解

    Unicode俗稱統一碼、萬國碼、單一碼、标準萬國碼。

    Unicode發展是由非營利機構統一碼聯盟所負責,其緻力于讓Unicode方案取代既有的字元編碼方案。因為既有的方案往往僅有有限的空間,亦不适用于多語環境。

     Unicode備受認可,并廣泛地應用于電腦軟體的國際化與本地化過程。有很多新科技,如可擴充置智語言、Java程式設計語言,以及現代的作業系統,都采用Unicode編碼。

Unicode的編碼和實作

大概來說,Unicode編碼系統可分為編碼方式和實作方式兩個層次。

[編輯]編碼方式

    統一碼的編碼方式與ISO 10646的通用字元集(Universal Character Set,UCS)概念相對應。目前實際應用的統一碼版本對應于UCS-2,使用16位的編碼空間。也就是每個字元占用2個位元組。這樣理論上一共最多可以表示216(即65536)個字元。基本滿足各種語言的使用。實際上目前版本的統一碼并未完全使用這16位編碼,而是保留了大量空間以作為特殊使用或将來擴充。

    上述16位統一碼字元構成基本多文種平面(Basic Multilingual Plane,簡稱BMP)。最新(但未實際廣泛使用)的統一碼版本定義了16個輔助平面,兩者合起來至少需要占據21位的編碼空間,比3位元組略少。但事實上輔助平面字元仍然占用4位元組編碼空間,與UCS-4保持一緻。未來版本會擴充到ISO 10646-1實作級别3,即涵蓋UCS-4的所有字元。UCS-4是一個更大的尚未填充完全的31位字元集,加上恒為0的首位,共需占據32位,即4位元組。理論上最多能表示231個字元,完全可以涵蓋一切語言所用的符号。

    基本多文種平面的字元的編碼為U+hhhh,其中每個h 代表一個十六進制數字,與UCS-2編碼完全相同。而其對應的4位元組UCS-4編碼後兩個位元組一緻,前兩個位元組則所有位均為0。

關于統一碼和ISO 10646及UCS的詳細關系 ,請參看通用字元集。

[編輯]實作方式

    Unicode的實作方式不同于編碼方式。一個字元的Unicode編碼是确定的。但是在實際傳輸過程中,由于不同系統平台的設計不一定一緻,以及出于節省空間的目的,對Unicode編碼的實作方式有所不同。Unicode的實作方式稱為Unicode轉換格式(Unicode Transformation Format,簡稱為UTF)

    例如,如果一個僅包含基本7位ASCII字元的Unicode檔案,如果每個字元都使用2位元組的原Unicode編碼傳輸,其第一位元組的8位始終為0。這就造成了比較大的浪費。對于這種情況,可以使用UTF-8編碼,這是一種變長編碼,它将基本7位ASCII字元仍用7位編碼表示,占用一個位元組(首位補0)。而遇到與其他Unicode字元混合的情況,将按一定算法轉換,每個字元使用1-3個位元組編碼,并利用首位為0或1進行識别。這樣對以7位ASCII字元為主的西文文檔就大大節省了編碼長度(具體方案參見UTF-8)。類似的,對未來會出現的需要4個位元組的輔助平面字元和其他UCS-4擴充字元,2位元組編碼的UTF-16也需要通過一定的算法進行轉換。

    再如,如果直接使用與Unicode編碼一緻(僅限于BMP字元)的UTF-16編碼,由于每個字元占用了兩個位元組,在Macintosh (Mac)機和PC機上,對位元組順序的了解是不一緻的。這時同一位元組流可能會被解釋為不同内容,如某字元為十六進制編碼4E59,按兩個位元組拆分為4E和59,在Mac上讀取時是從低位元組開始,那麼在Mac OS會認為此4E59編碼為594E,找到的字元為“奎”,而在Windows上從高位元組開始讀取,則編碼為U+4E59的字元為“乙”。就是說在Windows下以UTF-16編碼儲存一個字元“乙”,在Mac OS環境下開啟會顯示成“奎”。此類情況說明UTF-16的編碼順序若不加以人為定義就可能發生混淆,于是在UTF-16編碼實作方式中使用了大端序(Big-Endian, 簡寫為UTF-16 BE)、小端序(Little-Endian,簡寫為UTF-16 LE)的概念,以及可附加的位元組順序記号解決方案,目前在PC機上的Windows系統和Linux系統對于UTF-16編碼預設使用UTF-16 LE。(具體方案參見UTF-16)

    此外Unicode的實作方式還包括UTF-7、Punycode、CESU-8、SCSU、UTF-32、GB18030等,這些實作方式有些僅在一定的國家和地區使用,有些則屬于未來的規劃方式。目前通用的實作方式是UTF-16小端序(LE)、UTF-16大端序(BE)和UTF-8。在微軟公司Windows XP附帶的記事本(Notepad)中,“另存為”對話框可以選擇的四種編碼方式除去非Unicode編碼的ANSI(對于英文系統即ASCII編碼,中文系統則為GB2312或Big5編碼) 外,其餘三種為“Unicode”(對應UTF-16 LE)、“Unicode big endian”(對應UTF-16 BE)和“UTF-8”。

    目前輔助平面的工作主要集中在第二和第三平面的中日韓統一表意文字中,是以包括GBK、GB18030、Big5等簡體中文、繁體中文、日文、韓文以及越南喃字的各種編碼與Unicode的協調性被重點關注。考慮到Unicode最終要涵蓋所有的字元。從某種意義而言,這些編碼方式也可視作Unicode的出現于其之前的既成事實的實作方式,如同ASCII及其擴充Latin-1一樣,後兩者的字元在16位Unicode編碼空間中的編碼第一位元組各位全為0,第二位元組編碼與原編碼完全一緻。但上述東亞語言編碼與Unicode編碼的對應關系要複雜得多。

    在通常用法下,Java程式語言在通過

InputStreamReader

OutputStreamWriter

讀取和寫入串的時候支援标準UTF-8

摘自:維基百科Unicode,連結:http://zh.wikipedia.org/wiki/Unicode

備注:iso-8859-1是JAVA網絡傳輸使用的标準 ,這就是為什麼java web程式設計時,遇到亂碼問題時,有時用

String str = new String(filename.getBytes(),"ISO8859-1");轉碼的原因。

其它有助于加深了解的相關文章:

1.維基百科 UTF-8http://zh.wikipedia.org/wiki/UTF-8

2.維基百科 Unicode字元平面映射http://zh.wikipedia.org/wiki/%E5%9F%BA%E6%9C%AC%E5%A4%9A%E6%96%87%E7%A8%AE%E5%B9%B3%E9%9D%A2#.E5.9F.BA.E6.9C.AC.E5.A4.9A.E6.96.87.E7.A7.8D.E5.B9.B3.E9.9D.A2

3.Unicode 字元編碼表|漢字Unicode編碼的區間為:0x4E00→0x9FA5 http://467411.blog.163.com/blog/static/3353960920104122221346/

4.博文 Java編碼淺析 http://www.iteye.com/topic/311583

以下為非Unicode

5.維基百科 非國際碼ISO8859-1(即ISO/IEC 8859-1:1998,又稱Latin-1或“西歐語言”):http://zh.wikipedia.org/zh/ISO/IEC_8859-1

6.ANSI編碼  

為使計算機支援更多語言,通常使用 0x80~0xFF 範圍的 2 個位元組來表示 1 個字元。比如漢字“中”,在中文作業系統中,使用 [0xD6,0xD0] 這兩個位元組存儲。

不同的國家和地區制定了不同的标準,由此産生了 GB2312, BIG5, JIS 等各自的編碼标準。這些使用 2 個位元組來代表一個字元的各種漢字延伸編碼方式,稱為 ANSI 編碼。在簡體中文系統下,ANSI 編碼代表 GB2312 編碼,在日文作業系統下,ANSI 編碼代表 JIS 編碼。

  不同 ANSI 編碼之間互不相容,當資訊在國際間交流時,無法将屬于兩種語言的文字,存儲在同一段 ANSI 編碼的文本中。

繼續閱讀