Unicode,utf-8,utf-16,utf-32,ucs16,ucs32關係

來源:互聯網
上載者:User
編碼知識小結

最早的編碼是ascii,它只在1-127,用一個位元組就可以表示出來。並且這個位元組的第一個位是0。

後來,很多國家的語言發現ascii表示的字元太少,比如中文是不可能表示了來的,所以每個國家都發展了自己的擴充編碼,如中國的gb2312,台 灣的big5,日本的shift-jis等。各個國家的擴充編碼有一點是相同的,就是都採用了最大長度為2的變長編碼,這主要是為了和ascii保持兼 容。其編碼規範一般是,對於ascii裡的字元,保持和ascii編碼相容的格式,也就是第一個位是0,但是對於各國自己的文字,採用兩個位元組來表示,兩 個位元組能表示的字數是2^16=65535個,這一般來說是夠了。採用的作法一般是讓位元組的第一位為1,這樣,電腦看到字元的首字元為1,就會認為這是 個擴充的編碼,會把接下來跟著的一個字元加到一起,兩個字元當作一個字來處理。

gb2312就是這樣一個最大長度為2的可變長編碼,gb2312共收錄了7445個字元,其中漢定6763個,它的編碼範圍為2121H-777EH,可以看出,gb2312並沒有全部使用這兩個位元組的空間,它是可以再擴充的。

gbk就是在gb2312基礎上再擴充的。因為gb2312定義的6000多個漢字越來越不夠用了,所以出現了gbk編碼,gbk保持和 gb2312的相容,在此基礎上,增加了另一些不常見的漢字元號等。gbk中共收入21886人漢字和符號。gbk也是一種最大長度2位元組的變長編碼,它 的編碼範圍為8140-FEFE之間。

其它國家的擴充編碼(big5, shift-jis)等也都是採用和gb2312/gbk一樣的思路,使用最大兩位元組的變長編碼,因為這樣可以和ascii保持相容。

但是,中國的漢字其實不只這些,還有一些特別不常見的漢字,加一起一共好象有7萬多個,超過了兩位元組能表示的範圍。這種情況下,又產生了gb18030編碼。

gb18030是一個最大長度為4位元組的可變長編碼,它向下和gb2312,gbk保持相容,另外它又擴充了很多的字元,總共超過了7萬個,這樣 gb18030的編碼長度可能是1,2,4位元組,對於gb2312,gbk相容的部分,它使用兩位元組表示,當兩位元組不夠用的時候,它使用4位元組編碼。 gb18030的編碼空間約有160萬碼位,上前已編碼2萬多個。gb18030的範圍:一位元組部分從0x0-0x7F與ascii相容,二位元組部分,首 位元組從0x81-0xfe,尾位元組從0x40-0x7e以及0x80-0xfe,與gbk相容。四位元組部分,第一位元組從0x81-0xfe,第二位元組從 0x30-0x39,第三和第四位元組的範圍和前兩個位元組分別相同,四位元組部分覆蓋了從0x0080開始,除去二位元組部分已經覆蓋的所有 Unicode3.1碼位,也就是說,gb18030編碼在碼位空間上做到了與Unicode標準一一對應。

雖然各國都定義了自己的編碼,但是互相之間是不通用的,因為大家都只有兩位元組共65535個位置可以使用,大家都用這一段地區,但是又沒有形成統 一,比如你用哪段我用哪段,所以互相的編碼是不統一的,一段gb2312的編碼拿到shift-jis上解析就變成亂碼了。這種情況下,為了統一,產生了 Unicode編碼。

Unicode定義了百萬個以上的字元,包括了各個國家的編碼裡有的字元(如gb2312,gbk,big5等),如果把所有的字元用統一的格式表 示,需要4個位元組,實際上,這就是UTF32,Linux下就是使用UTF32方案。但是分析一下其實大部分字元都可以使用2個位元組表示,這樣可以節省空 間,比如Widnows上就是用兩個位元組的Unicode方案,也叫UTF16,在UTF16裡,對於兩個位元組不能表示的的字元,使用一種代理的手法來擴 展(其實就是在低兩個位元組上做一個標記,表示這是一個代碼,需要串連上隨後的兩個位元組,才能組成一個字元)。所以,一般來說,在Windows平台上提到 Unicode就是指UTF16,而在Linux下面提到Unicode是指UTF32。

Unicode的學名叫"Universal Multiple-Octer Coded Character Set",簡稱UCS,UCS是"Unicode Character Set"的縮寫,所以UCS其實就是指Unicode。Unicode規範的字元的編碼,UCS規定了怎麼用多個位元組表示字元。

UCS有兩種格式:UCS2和UCS4,UCS2就是用兩個位元組編碼,UCS4就是4個位元組(實際上只用了31位,最高位必須為0)。

UCS2和UCS4都是定長的編碼,UCS2有2^16=65535個碼位,UCS4有2^31=2147483648個碼位。

UCS4根據最高位為0的最高位元組分為2^7=128個group,每個group根據次高位元組分為256個plane,每個根據第3位元組分為 256行,每行包含256個cells。group 0的plane 0被稱為Basic Multilingual Plane,即BMP。也就是說UCS2其實只能表示UCS4中BMP的部分。對於BMP的UCS2和UCS4編碼的轉換很簡 單,UCS2->UCS4,只要在編碼前兩加個全是0的位元組,而UCS4->UCS2就是把編碼的前兩個全為0的位元組去掉。UCS2也就只能 表示BMP時而定義的<=65535個字元。不過,上前的UCS4規範還沒有字元被分配在BMP之外。(好象新的標準已經有在BMP之外的了吧,要 不然gb18030那些擴充字元在BMP裡應該是放不下的)。

Unicode是一種編碼方式,要把Unicode用於實際中還需要對Unicode進行編碼(UCS雖然好,但是它是不適合儲存到檔案系統中的。 因為ascii轉換成UCS2,只是在編碼前加一個0x0,用這些編碼會出現一些控制符,比如/等,這在unix和一些c函數中,會產生嚴重錯誤。),這 就產生了UTF-7,UTF-8,UTF-16,UTF-32。

utf-8是一種8位的字元集,編碼長度是可變的,從1個位元組到6個位元組不等,utf-8保持和ascii的相容。一般來說,utf-8用一個位元組 表示ascii字元,用兩個位元組表示西歐字元,用三個字元表示亞洲的大部分字元。Unix平台普遍支援utf-8,大部分html,以及檔案儲存體,傳輸等 都使用utf-8。

utf-16也是一種變長編碼,但是它不和ascii相容。utf-16是ucs2的超集,它實際上是ucs2加上附加字元的支援,也就是符合 Unicode4.0規範的UCS2。utf16至少使用2個位元組表示一個字元,在ucs2之外附加的字元部分使用4個位元組表示。所以utf-16要麼是 2個位元組,要麼是4個位元組。utf-16是windows平台上主要使用的編碼方案,主要在windows2000以上版本使用。windows下的 wchar_t就是兩個位元組,應該就是utf-16。

utf-32是一種定長編碼,它和UCS4幾乎是相同的。utf-32編碼每個碼使用4個位元組,linux下使用的是utf-32方案。

utf是編碼方案,所以還涉及到位元組序的問題。位元組順序標記(Byte Order Mark, 簡稱BOM)出現在Unicode流開端,說明編碼類別型。BOM是一個有點小聰明的想法:在UCS編碼中有一個叫做"zero width no-break space"的字元,編碼為FEFF,而FFFE在UCS中是不存在的字元,所以不應該出現在實際的傳輸中,UCS規範建議我們在傳輸位元組流前,先傳 輸"zero width no-break space",這樣拉收者收到這個字元時就可以通過它判斷位元組順序。下面是常用的BOM:

> UTF-16 big endian FE FF
> UTF-16 little endian FF FE
> UTF-32 bign endian 00 00 FE FF
> UTF-32 little endian FF FE 00 00
> UTF-8 little endian EF BB BF

當我們在Unicode流開頭讀到這些字元時就可以確認編碼的順序。utf-8因為是以位元組為單位進行編碼,所以不存在位元組順序問題,但可以用 BOM來表示編碼方式,字元"zero width no-break space"的utf-8編碼是EF BB BF。所以如果收到EF BB BF開頭的位元組流,就表明這是utf-8編碼。在windows下,如果用記事本存一下utf-8格式的檔案,其頭部就是以EF BB BF開頭的。在linux下,為了保持和ascii的相容,所有的utf-8檔案是不加EF BB BF頭的。

UTF-8設計之中的一個優點是它將一組碼點編碼成位元組流,而不是WORDS或者DWORDS,這樣可以忽略底層機器的位元組序(endian)問 題。這意味著你可以在兩台小尾位元組序和大尾位元組序的機器之間交換UTF-8流而不需要任何位元組重組或添加BOM。也就是說,你可以完全無視底層的體系架 構。

UTF-8編碼的另一個優點源於它從左至右儲存實際碼點的位元,做一個二進位形式的原始位元組排序,就可以將字串按碼點排序。這雖然不如按 locale定序進行排序那麼好,但對於無需理解UFF-8的底層系統來說,它終究提供了很簡易的一種排序方式,底層系統只需要知道如何排序原始位元組 就可以了。

總結:

Unicode是規範,其有UCS2和UCS4兩種格式。UCS2和UCS4都是定長的。基本上可以理解為UCS4就是UTF-32,而UCS2和UTF-16相容,只是UTF-16擴充了一些。

UTF是Unicode的實現,它分為utf-8,utf-16,utf-32幾種形式,其中utf-8和utf-16都是變長的,而utf-32是定長編碼。(其實還有utf-7等其它編碼存在)

附:UTF-8的位元組布局:

> 位元組數 位元 表示
> 1 7 0bbbbbbb
> 2 11 110bbbbb 10bbbbbb
> 3 16 1110bbbb 10bbbbbb 10bbbbbb
> 4 21 11110bbb 10bbbbbb 10bbbbbb 10bbbbbb
> 5 26 111110bb 10bbbbbb 10bbbbbb 10bbbbbb 10bbbbbb
> 6 31 1111110b 10bbbbbb 10bbbbbb 10bbbbbb 10bbbbbb 10bbbbbb
> 7 36 11111110 10bbbbbb 10bbbbbb 10bbbbbb 10bbbbbb 10bbbbbb 10bbbbbb
> 8 42 11111111 10bbbbbb 10bbbbbb 10bbbbbb 10bbbbbb 10bbbbbb 10bbbbbb 10bbbbbb

轉自:http://blog.csdn.net/meteor1113/archive/2009/07/15/4350390.aspx

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.