1. 程式人生 > >常用編碼學習

常用編碼學習

合成 info 計算 空格 法語 互聯網 國家 阿拉伯 strong

常用編碼

在計算機世界,所有信息都是用二進制存儲。每一個二進制有0和1兩種狀態。

所以8個二進制就可以組合成256種狀態,也就是一個字節。

也就是說,一個字節可以用來表示256種不同的狀態,每一個狀態對應一個符號,也就是256個符號,從00000000—11111111。

ASCII碼

一共規定了128個字符的編碼,包含大小寫字母、數字、還有空格等一些常用符號,這128個符號中有32個不能打印出來的控制符號。只占用了一個字節的後面7位,也就是最前面一位都是0.

大寫字母A是65,也就是二進制的01000001。

空格是32,也就是二進制的00100000。

非ASCII編碼

上面講的ASCII編碼規定的128個字符,對英語來說足夠用了,但是用來表示其他語言,128個符號不夠用。例如,法語字母上面有註音符號,它就無法用ASCII碼表示。於是,一些歐洲國家就決定,利用字節中閑置的最高位

編入新的符號。

比如,法語的é的編碼為130,二進制位10000010,這樣以來歐洲國家可以使用8個二進制的所有組合,也就是最多256個符號。

但是,這也有問題,130在法語編碼中表示é,而在希伯來語編碼中卻代表字母Gimel(?),在俄語編碼中又代表另一個符號。但是不管怎樣,所有這些編碼方式中,0—127表示的符號是不一樣的,不一樣的只是128—255的這一段。

至於亞洲國家的文字,額….漢字就10W+,256種符號肯定不夠,就必須使用多個字節表達一個符號。比如,簡體中文常見的編碼方式是GB2312,使用256個字節表示一個漢字,所以理論上最多表示256*256=65536個符號。

當然,世界上的編碼方式有很多,不止上面提到的這些。


Unicode

世界上存在著多種編碼方式,同一個二進制數字可以被解釋不同的符號。因此,要想打開一個文本文件,就必須知道它的編碼方式,否則用錯誤的編碼方式解讀,就會出現亂碼。

Unicode是一種把世界上所有符號都納入其中,每一個符號都給予了一個獨一無二的編碼,那麽亂碼問題就會消失。

Unicode是一個很大的集合,現在的規模可以容納100多萬個符號,每個符號的編碼都不一樣,比如:

U+0639表示阿拉伯字母Ain。

U+0041表示英語的大寫字母A

U+4E25 表示漢字嚴

Unicode的問題

Unicode只規定了符號的二進制代碼,卻沒有規定這個二進制代碼應該如何存儲。

例如:漢字轉化為二進制是100111000100101,足足有15位,也就是最少需要兩個字節,甚至有更大的符號,需要3個字節或者4個字節,甚至更多。

這就有了兩個嚴重的問題:

1.如何區分Unicode和ASCII,計算機怎麽知道三個字節表示一個符號,而不是表示三個符號呢?

2.我們已經知道英文字母只用一個字節表示就足夠了,如果Unicode同一規定,每個符號用三個或四個字節表示,那麽每個英文字母前都必須有2—3個字節是0,這對於數據存儲來說是極大的浪費,文本文件的大小因此會打出2—3倍,這是無法接受的。

UTF-8閃亮登場

UTF-8Unicode的一種實現方式,其他實現方式還有UTF-16(字符用2—4個字節表示),UTF-32(字符用四個字節表示),不過其他的在互聯網上基本不用,UTF-8就是為了統一編碼方式產生的,也是互聯網上使用最廣的一種Unicode的實現方式。

UTF-8的最大特點,就是它是一種邊長的編碼方式,可以使用1—4個字節來表示一個符號,根據不同的符號而變化字節長度。

它的規則很簡單,只有兩條:

對於單字節的符號,字節的第一位為0,後面7位為這個符號的Unicode碼。因此,對於英文字母,UTF-8和ASCII碼是相同的。

對於n字節的符號(n>1),第一個字節的前n位都設為1,第n+1位設為0,後面字節的前兩位一律為10。

漢字的Unicode是4E25(100111000100101),需要用三個字節存儲,根據上面的規則,即格式為:

1110xxxx 10xxxxxx 10xxxxxx

記住,二進制是從後往前存儲的,讀也是從後往前讀的,所以我們先填充第三個字節,從二進制的後面讀取,填充完後變成了:

1110xxxx 10xxxxxx 10100101

再根據同樣規則填充第二個字節,填充完後變成了:

1110xxxx 10111000 10100101

最後填充最後一個字節:

1110x100 10111000 10100101

不對啊,怎麽少了一個字節?沒事,少了的用0補位:

11100100 10111000 10100101

Unicode與UTF-8的轉換

這兩種編碼的轉換可以通過程序實現,在Windows平臺下,最簡單的方法是,通過記事本另存為:
技術分享圖片

ACSI就是ACSII,是Windows英文系統的默認的編碼格式,但是對於Windows簡體中文版默認就是GB2312,針對繁體中文版默認就是Big5。

而現顯示的Unicode都是使用UCS-2編碼方式存儲的Unicode字節,只不過默認是little endian格式,而另一個選項是Unicode big endian格式。

Unicode little endianUnicode big endian的轉換:

簡單舉個例子,UCS-2格式可以存儲Unicode碼。漢字的Unicode碼為4E25,需要用兩個字節存儲,一個字節是4E,另一個是25。4E在前,25在後就是Big endian(從前往後),25在前,4E在後,就是Little endian(從後往前)。

那計算機怎麽知道某一個文件到底采用哪一種方式編碼呢?

Unicode規範定義,每一個文件最前面分別加入一個表示編碼順序的字符,這個字符的名字叫做 “zero width no-break space” ,用FEFF表示,正好是兩個字節。

如果一個文本文件的頭兩個字節是FE FF,表示是Big endian方式,如果頭兩個字節是FF FE,表示是Little endian方式。

本文大部分來自阮一峰大神的個人博客:http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html

常用編碼學習