【編程基礎】—字符編碼之二三事

相信大家在寫腳本或者平時的測試過程中肯定都碰到過亂碼,面對自己不認識的怪異字符,肯定會不知所措。今天這篇文章就帶大家看看編碼格式的發展歷程,讓你碰到問題時有思路可循。

編碼格式發展史

ASCII

衆所周知,世界上第一臺計算機是美國人在20世紀40年代發明的,當時確定計算機以二進制(0101)的方式來存儲數據,也就是說能在計算機上顯示的所有字符:數字、大小寫字母、符號等最終都需要轉成計算機可識別的二進制。因此,必須建立一套從字符到二進制的對應關係,於是 美國國家標準協會(American National Standard Institution) 就收集了當時美國所使用的所有字符(共128個)。因爲一個字節包含8位,共有256種二進制組合(2的8次方),所以單個字節就能覆蓋所有的字符,並且單個字節的最高位也用不上,因爲後7位就可以表達128個字符。ASCII表於1967年正式發佈,共包括33個控制字符和95個可顯示字符 。

0000 0000-0001 1111 共33種狀態表示特殊的終端控制(例如打印機響鈴)(0-33)0011 0000-0011 1010 共10個表示0-9十個數字0100 0001-0101 1010 共26個表示大寫字母0110 0001-0111 1010 共26個表示小寫字母   外加33個符號(運算符、特殊符號)   一共128個佔7位 高位不用直接補0。

上面引入了一些基礎概念,我們簡單介紹下:

  • 位(bit):計算機中最小單位,用二進制的0/1表示。

  • **字節(byte):**每8位組成一個字節。

  • **字符:**我們平時可見的文字、字母、符號、數字等。

  • **字符集:**多個字符的集合。

  • **編碼(encode):**將字符轉換成計算機可識別的二進制代碼(0/1代碼)。

  • **解碼(decode):**將計算機表示的0/1編碼轉換成肉眼可見的字符。

EASCII

隨後,計算機傳入歐洲,歐洲人發現ASCII無法展示他們自己特有的一些字符(表格符號、計算符號、希臘字母和特殊的拉丁符號)。歐洲人靈光一現:ASCII不是沒有用到最高位嘛,正好可以利用起來,於是他們將ASCII編碼的高位從0變爲1,擴展出128個二進制數(10000000~11111111)。

但是實際使用過程中,由於不同國家的字符略有不同,因此有可能同一個二進制數字,但是代表的字符卻是不同的, 比如,1000 0010在法語編碼中代表了é,在希伯來語編碼中卻代表了字母Gimel (?),在俄語編碼中又會代表另一個符號 。不過編碼的0-127是和ASCII完全一致的,唯一有區別的是後面128-255之間的字符不同。這就是EASCII,它完全兼容ASCII。

GB2312

再往後,計算機被引入到亞洲,中華文化博大精深,漢字共包含了古文、現代文字等近十萬個文字,就算只考慮我們常用字也有6000多個漢字,所以ASCII肯定是沒辦法滿足需求了。於是,在1981年,國家標準化管理委員會正式制定了 中華人民共和國國家標準簡體中文字符集 ,被稱之爲GB2312。

它共包含7445個字符,6763個漢字和682個其他字符(拉丁字母、希臘字母、日文平假名及片假名字母、俄語西裏爾字母) ,每個漢字及符號都用兩個字節來存儲。

BIG5

GB2312是簡體中文字符集,但是中國的港澳臺同胞們使用的卻是繁體字,於是在1984年,中國又聯合部分臺灣的廠商,一起推出了BIG5編碼,它共收錄13,060個漢字及441個符號,也採用兩個字節來存儲字符。

Unicode

隨着計算機的普及和發展,越來越多的國家希望自己的文字可以顯示在計算機上,於是他們就開始制定自己的編碼格式。但是這樣帶來的後果是,在自己國家電腦上寫的好好的一份文件,copy到其他國家的電腦上就完全變成亂碼,這挺可怕的,每個國家都活在自己的小世界裏,沒辦法跟其他國家的人交流。

於是國際標準化組織(ISO)及國際電工委員會(IEC)於1984年聯合成立了ISO/IEC小組,核心目的是開發一套統一的編碼格式。1991年,推出了Unicode1.0,不過它並沒有包含 CJK字符(即中日韓) ,可能是因爲亞洲這幾個國家的編碼太複雜了。

ISO/IEC 8859

還記得上面我們提到ESCAII時講過,歐洲國家在使用ESCAII時會出現,在128-255之間表示不同國家字符時會略有不同。ISO/IEC小組在1984年成立後的第三年(即1987年)開始啓動ISO 8859標準的編寫,ISO 8859是一系列單字節字符集的標準,採用了ESAII的部分編碼,主要是爲世界各地的不同語言(除中日韓)而單獨編寫的字符集,一共定義了15個字符集:從ISO 8859-1 到ISO 8859-16,需要注意的是沒有ISO 8859-12, 據說-12號本來是預留給印度天城體梵文的,但後來卻不了了之 。

比較常用的是ISO 8859-1,有些環境也稱之爲Latin-1,某些軟件,比如mysql的默認編碼格式就是Latin-1。

UCS

UCS( Universal Character Set  通用字符集)是一個超級大的字符集,它包含了已知的所有字符,並且它爲每一個字符都分配一個唯一的代碼。這其實保證了UCS與其他字符的雙向兼容,即將任何編碼格式的文本轉換成UCS,然後再翻譯回原編碼,不會丟失任何信息。

UCS有兩種編碼方案:UCS-2和UCS-4,UCS-2使用兩個字節編碼(Unicode默認以UCS-2編碼),UCS-4使用四個字節編碼。UCS-2其實可以容納的字符數爲65536(2的16次方),而UCS-4可以容納的字符數爲2147483648(2的31次方)。其實對於UCS-2已經是完全夠用了,基本可以包含世界所有國家的常用文字,如果需要考慮一些偏僻字,那麼UCS-4則絕對可以滿足了。

有的人可能有疑問,爲啥有了Unicode還會有UCS,其實UCS是ISO/IEC推出的一種編碼方式,而Unicode起初是美國的一些大公司聯盟爲了對抗UCS而推出的,後來兩個組織發現,他們做的大部分事情都是重複的,乾脆握手言和吧,於是後面就聯手發佈Unicode的後續版本,不過UCS也作爲單獨的版本發佈過。

UTF

隨着計算機網絡的發展,Unicode如何在網絡上傳輸也是必須考慮的問題,因爲Unicode採用兩個字節編碼,如果用Unicode去表示一個ASCII,那麼其第一個字節就始終爲0(因爲ASCII只需要一個字節)。這就造成了較大的空間浪費,於是UTF系列的編碼應運而生,其最大特別是可變字節編碼,這樣可以節省帶寬,提高網絡傳輸效率。

UTF-8: 使用1~4個字節編碼,其中ASCII用1個字節編碼、 拉丁文、希臘文 等用2個字節編碼、大部分國家的常用字用3個字節編碼、其他極少使用的生僻字用4個字節編碼。

UTF-16: 使用2個或4個字節編碼,其中ASCII用2個字節編碼、其他字符使用四個字節編碼

UTF-32:  等同於UCS-4,對於所有字符都使用四個字節來編碼

GB13000

前面提到1993年,ISO/IEC組織推出了Unicode1.0,不包含中日韓語言,但是緊接着ISO/IEC就推出了Unicode1.1版本,支持了中日韓語言。中國的標準組織考慮到自己也得有一個字符集,能夠走向世界,於是將Unicode1.1中所有的內容全部搬過來,然後又經過部分修訂完善,發佈了GB130000。

GBK

GBK(K其實是拼音Kuo Zhan的首字母)是對漢字編碼的擴展,這個微軟指定的編碼格式。隨着計算機在中國的普及,微軟意識到中國是一個巨大的市場,但是微軟的系統在中國佈局,肯定要面對編碼兼容性問題,之前的GB2312基本滿足了漢字的處理需求, 但對於人名、古漢語等方面出現的罕用字和繁體字,GB2312不能處理 。因此微軟就利用GB2312中未被利用的編碼空間,收錄了GB130000中所有的字符,制定了GBK編碼(還是兩個字節),因此GBK是完全兼容G2312編碼的。

GB18030

雖然GBK和GB130000編碼已經包含了大部分的漢字和繁體字,但是並沒有考慮到中國的少數民族的語言(中國有56個民族,12個民族有自己的語言)。在2000年,中國標準化組織又起草了GB18030標準,它參考UTF-8的編碼方式,採用多編碼方式(1或2或4個字節進行編碼)。在2005年,發佈GB18030-2005,共包含70244個漢字 。

ANSI

其實ANSI並不是一種特定的編碼格式,是隻存在於windows上的一種編碼,猜測可能是微軟爲了能統一顯示不同國家操作系統的編碼而推出的。比如在在簡體中文Windows操作系統中,ANSI 編碼代表 GBK 編碼;在繁體中文Windows操作系統中,ANSI編碼代表Big5;在日文Windows操作系統中,ANSI 編碼代表 Shift_JIS 編碼 ,在美國的windows操作系統中,就代表ASCII。windows主要通過 code page 來區分不同的編碼格式,你可以在windows cmd窗口通過chcp命令切換code page。

總結

在平時的工作當中,如果碰到亂碼,不要驚慌,只需要分析文件的編碼格式、代碼中對編碼的處理方式等等(具體問題還得具體分析),在之後的文章中,牽扯到具體的問題,我們再具體分析。

發佈了20 篇原創文章 · 獲贊 0 · 訪問量 4075
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章