先說兩個基礎知識。php
(1)計算機內部,數據是由0,1組成的;python
(2)計算機最小的數據單位,就是一個二進制單位即bit,接下來就是8個二進制單位表示一個字節(Byte)。windows
ASCII碼(American Standard Code for Information Interchange,美國信息交換標準)只能用0,1表示26個字母(大小寫共計52個),阿拉伯數據(10個),還有一些標點符號、運算符號以及控制符(如換行,回車等)。網站
若是須要很是清楚的知道對應規則,能夠查閱ASCII碼錶。編碼
須要表示的很少,因此僅拿出7位數字(0-127)來表示字符,這叫作基礎ASCII碼。剩下的(128-255)則留做擴展用。這也就意味着基礎ASCII碼字節的最高位永遠是0。spa
在Python裏能夠看一下。操作系統
print('a') #打印字母a print(ord('a')) #打印出字母a的ASCII碼十進制 print(bin(ord('a'))) #打印出字母a的ASCII碼二進制
輸出結果.net
a 97 0b110 0001 #0b表示是二進制,最高位是0,但python輸出自動省略了
表示漢字的話,ASCII碼就不夠用了,那麼就拿多個字節來表示。不一樣國家語言文字的編碼都要遵照一個共同的法則,就是要對ASCII碼保持向下兼容。翻譯
也就是,最核心的就是原來ASCII碼最高位爲0,那麼若是仍然是英文字母,這個最高位就仍是0,而不是英文字母,這個最高位就變成1。3d
以咱們中文而論,咱們國家在 1981 年發佈了簡體中文漢字編碼國家標準,也稱爲 GB2312。
它的大體思想是使用1個94*94 的矩陣將全部字符存儲起來。行稱爲區,列成爲位。而中文字符也按照經常使用程度分爲一級漢字和二級漢字。每個中文字符都是用區字節和位字節來表示的。爲了和 ASCII 碼兼容,做了以下規定:一個小於 127 字符的意義與原來ASCII 碼相同,但兩個大於 127 的字符連在一塊兒就表示的是一個漢字。一個漢字。這樣實際上就足夠有214 = 16384種表示方法,這個數字不只可以涵蓋絕大部分的中文簡體字,還能夠把數學符號,羅馬希臘字母以及日本的假名都編進去,甚至原來在ASCII 碼裏的數字、標點和字母也編了進去。可是這些數字和字母和原來 ASCII 碼不一樣的是它是用兩個字節表示的,所以稱做全角符號,而原來的 ASCII 碼字符則還稱做半角符號。
GB2312編碼對所收錄字符進行了「分區」處理,共94個區,每區含有94個位,共8836個碼位。這種表示方式也稱爲區位碼。
01-09區收錄除漢字外的682個字符。
10-15區爲空白區,沒有使用。
16-55區收錄3755個一級漢字,按拼音排序。
56-87區收錄3008個二級漢字,按部首/筆畫排序。
88-94區爲空白區,沒有使用。
舉例來講,「啊」字是GB2312編碼中的第一個漢字,它位於16區的01位,因此它的區位碼就是1601。
具體的能夠參看這個網站GB2312編碼
但因爲要和 ASCII 碼兼容,不管區碼仍是位碼都要最高位爲1。理論上咱們只須要將每一個碼加上128(十六進制表示0x80),可是GB2312規定的是每一個碼加上160(十六進制表示0xa0)。這樣「啊」在計算機裏真正的存儲爲0xb0,0xa1。
可是GB2312實際上只收錄了6763 個漢字,對於絕大部分應用是夠了。可是對於特殊字就很差辦了。還有就是臺灣人民所使用的繁體字(big5編碼),也不支持。
原來 GB2312 規定兩個字節最高位都不能是1,而 GBK 規定首字節的最高位爲1,咱們就認爲後面是兩個字節來表示漢字,而第2個字節的最高位能夠不是1。因而乎就大大擴展了編碼範圍,這一次收錄了21003個漢字,並且將繁體字也歸入進來。
1984年,臺灣五大廠商宏碁、神通、佳佳、零壹以及大衆一同制定了一種繁體中文編碼方案,因其來源被稱爲五大碼,英文寫做Big5,後來按英文翻譯回漢字後,廣泛被稱爲大五碼。目前,Big5編碼在臺灣、香港、澳門及其餘海外華人中廣泛使用,成爲了繁體中文編碼的事實標準。因爲Big5編碼和GB2312編碼是衝突的,所以一個文本內不可能既支持BIG5,也支持GB2312。實際上雖然GBK能夠支持繁體中文,可是它和BIG5編碼也是相互衝突,並不兼容的。
不只僅中文如此,日文、韓文以及其餘國家的文字也都是如此。所以這一類咱們稱之爲多字節字符編碼(MBCS),可是因爲實際上都是兩個字節,所以有的時候咱們也將其稱之爲雙字節字符編碼(DBCS)。微軟也將其稱之爲美國國家標準(ANSI),因此咱們在使用操做windows系統的記事本的時候,在另存時選擇字符編碼爲ANSI,若是你是簡體中文操做系統,其實就是GBK,而若是是繁體操做系統的話,則是BIG5編碼。IBM爲了統一各國字符編碼系統,他把全部的編碼編成了一本厚厚的「書」,中文的GBK編碼在936頁,所以也稱之爲CodePage-936,而BIG5在950頁,也稱之爲CodePage-950。
CodePage,MBCS,DBCS和ANSI這四個概念,實際上是同一個意思,它們均不特指某一個字符編碼,而是在不一樣的地區和國家包括特定的含義。
最先的Unicode編碼是經過兩個字節來進行編碼,可是咱們已經知道兩個字節最多隻能有\(2^{16}=65,536\)種表示方法,這個用來表示基於字母的語言是夠用的,可是對於相似中文、韓文、日文這樣的文字,那麼這個編碼還不夠。因而Unicode拿出了四個字節來進行存儲。第1個字節稱之爲組,第2個字節稱之爲面,第3個字節稱之爲行,第4個字節稱之爲點。其中第0組,第0個面,會涵蓋絕大部分咱們所使用的文字,所以也稱之爲基本多語種平面(Basic Multilingual Plane)。
實際上,咱們如今僅用了17個平面(從平面0-平面16)來存儲全世界全部的文字,這樣其實是總共用了\(65,536×17=1114112\)個碼位。也就是說全世界全部的文字都可以在0-1114111當中找到,這裏麪包括了71226個漢字。
規定了這全部文字的編碼後,接下來面臨的一個問題就是如何將這些文字編碼以字節的形式表示在計算機裏,這個過程咱們也稱之爲Encoding過程。
因而出現了各類編碼轉換方法(Universal Transformation Formats),而最爲著名的就是UTF-8。這個也促成了Unicode編碼和計算機存儲的分離。UTF-8的編碼原則有如下2條:
若是一個字符的Unicode編碼小於128,這用一個字節表示,保證了兼容ASCII碼;
若是一個字符大於128,這按照以下表規則編碼成二、3或者4個字節。
【參考】
[1]《爬蟲基礎知識之字符編碼(以Python爲例)》互聯網空間數據挖掘研究小組
[2] GB2312編碼表