——每個軟件開發人員應該無條件掌握的知識!
——Unicode偉大的創想!
相信大家一定碰到過,打開某個網頁,卻顯示一堆像亂碼,如"бЇЯАзЪСЯ"、"�????????"?還記得HTTP中的Accept-Charset、Accept-Encoding、Accept-Language、Content-Encoding、Content-Language等消息頭字段?這些就是接下來我們要探討的。
1.基礎知識
計算機中儲存的信息都是用二進制數表示的;而我們在屏幕上看到的英文、漢字等字符是二進制數轉換之後的結果。通俗的說,按照何種規則將字符存儲在計算機中,如'a'用什麼表示,稱爲"編碼";反之,將存儲在計算機中的二進制數解析顯示出來,稱爲"解碼",如同密碼學中的加密和解密。在解碼過程中,如果使用了錯誤的解碼規則,則導致'a'解析成'b'或者亂碼。
字符集(Charset):是一個系統支持的所有抽象字符的集合。字符是各種文字和符號的總稱,包括各國家文字、標點符號、圖形符號、數字等。
字符編碼(Character Encoding):是一套法則,使用該法則能夠對自然語言的字符的一個集合(如字母表或音節表),與其他東西的一個集合(如號碼或電脈衝)進行配對。即在符號集合與數字系統之間建立對應關係,它是信息處理的一項基本技術。通常人們用符號集合(一般情況下就是文字)來表達信息。而以計算機爲基礎的信息處理系統則是利用元件(硬件)不同狀態的組合來存儲和處理信息的。元件不同狀態的組合能代表數字系統的數字,因此字符編碼就是將符號轉換爲計算機可以接受的數字系統的數,稱爲數字代碼。
2.常用字符集和字符編碼
常見字符集名稱:ASCII字符集、GB2312字符集、BIG5字符集、GB18030字符集、Unicode字符集等。計算機要準確的處理各種字符集文字,需要進行字符編碼,以便計算機能夠識別和存儲各種文字。
2.1. ASCII字符集&編碼
ASCII(American Standard Code for Information Interchange,美國信息交換標準代碼)是基於拉丁字母的一套電腦編碼系統。它主要用於顯示現代英語,而其擴展版本EASCII則可以勉強顯示其他西歐語言。它是現今最通用的單字節編碼系統(但是有被Unicode追上的跡象),並等同於國際標準ISO/IEC 646。
ASCII字符集:主要包括控制字符(回車鍵、退格、換行鍵等);可顯示字符(英文大小寫字符、阿拉伯數字和西文符號)。
ASCII編碼:將ASCII字符集轉換爲計算機可以接受的數字系統的數的規則。使用7位(bits)表示一個字符,共128字符;但是7位編碼的字符集只能支持128個字符,爲了表示更多的歐洲常用字符對ASCII進行了擴展,ASCII擴展字符集使用8位(bits)表示一個字符,共256字符。ASCII字符集映射到數字編碼規則如下圖所示:
ASCII的最大缺點是隻能顯示26個基本拉丁字母、阿拉伯數目字和英式標點符號,因此只能用於顯示現代美國英語(而且在處理英語當中的外來詞如naïve、café、élite等等時,所有重音符號都不得不去掉,即使這樣做會違反拼寫規則)。而EASCII雖然解決了部份西歐語言的顯示問題,但對更多其他語言依然無能爲力。因此現在的蘋果電腦已經拋棄ASCII而轉用Unicode。
2.2. GBXXXX字符集&編碼
計算機發明之處及後面很長一段時間,只用應用於美國及西方一些發達國家,ASCII能夠很好滿足用戶的需求。但是當天朝也有了計算機之後,爲了顯示中文,必須設計一套編碼規則用於將漢字轉換爲計算機可以接受的數字系統的數。
天朝專家把那些127號之後的奇異符號們(即EASCII)取消掉,規定:一個小於127的字符的意義與原來相同,但兩個大於127的字符連在一起時,就表示一個漢字,前面的一個字節(他稱之爲高字節)從0xA1用到 0xF7,後面一個字節(低字節)從0xA1到0xFE,這樣我們就可以組合出大約7000多個簡體漢字了。在這些編碼裏,還把數學符號、羅馬希臘的 字母、日文的假名們都編進去了,連在ASCII裏本來就有的數字、標點、字母都統統重新編了兩個字節長的編碼,這就是常說的"全角"字符,而原來在127號以下的那些就叫"半角"字符了。
上述編碼規則就是GB2312。GB2312或GB2312-80是中國國家標準簡體中文字符集,全稱《信息交換用漢字編碼字符集·基本集》,又稱GB0,由中國國家標準總局發佈,1981年5月1日實施。GB2312編碼通行於中國大陸;新加坡等地也採用此編碼。中國大陸幾乎所有的中文系統和國際化的軟件都支持GB2312。GB2312的出現,基本滿足了漢字的計算機處理需要,它所收錄的漢字已經覆蓋中國大陸99.75%的使用頻率。對於人名、古漢語等方面出現的罕用字,GB2312不能處理,這導致了後來GBK及GB 18030漢字字符集的出現。下圖是GB2312編碼的開始部分(由於其非常龐大,只列舉開始部分,具體可查看GB2312簡體中文編碼表)於GB 2312-80只收錄6763個漢字,有不少漢字,如部分在GB 2312-80推出以後才簡化的漢字(如"囉"),部分人名用字(如中國前總理朱鎔基的"鎔"字),臺灣及香港使用的繁體字,日語及朝鮮語漢字等,並未有收錄在內。於是廠商微軟利用GB 2312-80未使用的編碼空間,收錄GB 13000.1-93全部字符制定了GBK編碼。根據微軟資料,GBK是對GB2312-80的擴展,也就是CP936字碼表 (Code Page 936)的擴展(之前CP936和GB 2312-80一模一樣),最早實現於Windows 95簡體中文版。雖然GBK收錄GB 13000.1-93的全部字符,但編碼方式並不相同。GBK自身並非國家標準,只是曾由國家技術監督局標準化司、電子工業部科技與質量監督司公佈爲"技術規範指導性文件"。原始GB13000一直未被業界採用,後續國家標準GB18030技術上兼容GBK而非GB13000。
GB 18030,全稱:國家標準GB 18030-2005《信息技術 中文編碼字符集》,是中華人民共和國現時最新的內碼字集,是GB 18030-2000《信息技術 信息交換用漢字編碼字符集 基本集的擴充》的修訂版。與GB 2312-1980完全兼容,與GBK基本兼容,支持GB 13000及Unicode的全部統一漢字,共收錄漢字70244個。GB 18030主要有以下特點:
- 與UTF-8相同,採用多字節編碼,每個字可以由1個、2個或4個字節組成。
- 編碼空間龐大,最多可定義161萬個字符。
- 支持中國國內少數民族的文字,不需要動用造字區。
- 漢字收錄範圍包含繁體漢字以及日韓漢字
本規格的初版使中華人民共和國信息產業部電子工業標準化研究所起草,由國家質量技術監督局於2000年3月17日發佈。現行版本爲國家質量監督檢驗總局和中國國家標準化管理委員會於2005年11月8日發佈,2006年5月1日實施。此規格爲在中國境內所有軟件產品支持的強制規格。
2.3. BIG5字符集&編碼
Big5,又稱爲大五碼或五大碼,是使用繁體中文(正體中文)社區中最常用的電腦漢字字符集標準,共收錄13,060個漢字。中文碼分爲內碼及交換碼兩類,Big5屬中文內碼,知名的中文交換碼有CCCII、CNS11643。Big5雖普及於臺灣、香港與澳門等繁體中文通行區,但長期以來並非當地的國家標準,而只是業界標準。倚天中文系統、Windows等主要系統的字符集都是以Big5爲基準,但廠商又各自增加不同的造字與造字區,派生成多種不同版本。2003年,Big5被收錄到CNS11643中文標準交換碼的附錄當中,取得了較正式的地位。這個最新版本被稱爲Big5-2003。
Big5碼是一套雙字節字符集,使用了雙八碼存儲方法,以兩個字節來安放一個字。第一個字節稱爲"高位字節",第二個字節稱爲"低位字節"。"高位字節"使用了0x81-0xFE,"低位字節"使用了0x40-0x7E,及0xA1-0xFE。在Big5的分區中:
0x8140-0xA0FE |
保留給用戶自定義字符(造字區) |
0xA140-0xA3BF |
標點符號、希臘字母及特殊符號,包括在0xA259-0xA261,安放了九個計量用漢字:兙兛兞兝兡兣嗧瓩糎。 |
0xA3C0-0xA3FE |
保留。此區沒有開放作造字區用。 |
0xA440-0xC67E |
常用漢字,先按筆劃再按部首排序。 |
0xC6A1-0xC8FE |
保留給用戶自定義字符(造字區) |
0xC940-0xF9D5 |
次常用漢字,亦是先按筆劃再按部首排序。 |
0xF9D6-0xFEFE |
保留給用戶自定義字符(造字區) |