天天看點

編碼史記字元編碼的故事

昨天聽了一個同僚的編碼講座,很精彩。想起了要寫這個文章分享一下各種編碼是如何産生的。

字元是什麼?就是有意義的圖形,比如a,中等。在不同的國家代表不同的意思。

但是在計算機世界中隻有0和1,好了,如何用0和1将這些字元表示出來呢?這就是編碼存在的意義。

編碼一點也不高深,就是一個計算機的01和字元ab的簡單映射。

歐洲人出場了。歐洲是有好多個國家的,他們的每個國家也都有自己的文字,比如拉丁文,希臘文等。怎麼辦呢?于是想到,你美國人指定的ascii碼表裡面不是隻有127個字元嗎,後面128-255的字元不是說待定嗎,好吧,我們就不客氣了。于是歐洲人就将各種奇怪的語言塞入127後面的字元中,形成了一系列的iso 8859字元集。比如希臘文塞入ascii,就形成了iso/iec 8859-7,西歐語種塞入ascii就形成了iso/iec 8859-1,iso/iec 8859-1也叫做latin-1。(對,就是mysql裡面經常見到的編碼)

iso/iec 8859-1 (latin-1) - 西歐語言 

iso/iec 8859-2 (latin-2) - 中歐語言 

iso/iec 8859-3 (latin-3) - 南歐語言。世界語也可用此字元集顯示。 

iso/iec 8859-4 (latin-4) - 北歐語言 

iso/iec 8859-5 (cyrillic) - 斯拉夫語言 

iso/iec 8859-6 (arabic) - 阿拉伯語 

iso/iec 8859-7 (greek) - 希臘語 

iso/iec 8859-8 (hebrew) - 希伯來語(視覺順序) 

iso 8859-8-i - 希伯來語(邏輯順序) 

iso/iec 8859-9(latin-5 或 turkish)- 它把latin-1的冰島語字母換走,加入土耳其語字母。 

iso/iec 8859-10(latin-6 或 nordic)- 北日耳曼語支,用來代替latin-4。 

iso/iec 8859-11 (thai) - 泰語,從泰國的 tis620 标準字集演化而來。 

iso/iec 8859-13(latin-7 或 baltic rim)- 波羅的語族 

iso/iec 8859-14(latin-8 或 celtic)- 凱爾特語族 

iso/iec 8859-15 (latin-9) - 西歐語言,加入latin-1欠缺的芬蘭語字母和大寫法語重音字母,以及歐元(€)符号。 

iso/iec 8859-16 (latin-10) - 東南歐語言。主要供羅馬尼亞語使用,并加入歐元符号。 

接着偉大的中國人也開始使用上電腦了。中文可不得了,文字博大精深,字元遠遠超過了256個。是以我們無法使用ascii的擴充了。怎麼辦呢? 1981年的時候,國家派一批人來做了這個事情,他們統計出所有的中文大概有6000多個字元(後來證明這些人的水品也是有限,好多字元都沒有搜出來,于是就有了多種的中文編碼),用兩個位元組(16bit)來表示,16bit能表示的是65536個字元,太夠了。我們将16bit分為前8bit和後8bit 

如果前8bit小于127(英文ascii),那麼這個8bit就是表示英文 

如果前8bit大于127,那麼這8bit和後面的8bit合起來表示一個中文

gb是啥意思?國标。

好了,後來某些上司發現,他的名字沒法編碼了,這個問題出來了。6000個漢字還不足以囊括所有中文,國家在1995年又組織了一批人,繼續搜羅一些生僻字,一共搜集出了21886個漢字和字元,形成了gbk編碼,gbk編碼向下相容gb2312。

k是啥意思?擴充。

再後來發現了,一些滿文,蒙古文啥的少數名族的語言沒有編輯到gbk中,繼續編輯收錄,形成了gb18030編碼。

big5是什麼意思? 

五種中文套裝軟體:文書處理,資料庫,試算表,通訊,繪圖。大緻的意思是這套編碼主要使用于這5個領域

各個國家使用各個國家自己的編碼有沒有很繁瑣?于是大家很期盼有一種統一的編碼形式出現。unicode編碼出現了。unicode使用的通用的字元集叫做ucs。這個字元集就是一個大的字元空間,每個語種都在這個字元空間内劃分一段領域。現在應用的ucs是ucs-2,意思就是不管是英文中文,統一使用兩個位元組(16bit)來進行字元配置設定。ucs-2字元集可以表示216(即65536)個字元。已經基本滿足世界上所有語言了。如果不夠怎麼辦?已經有預定方案ucs-4(用4個位元組表示一個字元)。

切記:utfxx是unicode的具體實作方式。

utf-16是unicode最基本的實作。unicode使用16bit表示一個字元,utf-16就是直接将字元集的映射搬過來而已。

utf-8這種編碼是怎麼回事呢? 

英文字元,和ascii碼一樣,占用一個位元組 

其他語種,每種語種配置設定一個模闆,這個模闆有16bit,24bit,甚至還有32bit的。各個語種根據這個模闆,将自己的語言轉化成模闆要求的編碼(utf-8) 

這裡示範一個中文字“漢” 

比如中文分到的模闆是1110xxxx 10yyyyyy 10zzzzzz 

漢字的unicode編碼是0x6c49,二進制是0110 1100 0100 1001 

将這個二進制按照模闆的x,y,z順序插入 

得到11100110 10110001 10001001 就是e6 b1 89 

好了…大家看出這個對中文有什麼不好的嗎?原先一個中文使用utf-16隻需要兩個位元組,但是使用utf-8卻需要3個位元組,如果一個網頁有1w個中文字,那麼我們就需要多傳輸1w個位元組,帶寬啊!! 現在就明白了,為什麼國内一些網站,比如sina,它的編碼規則是使用gbk了吧!

下面再說一下很多編輯器的自動編碼比對的問題。編輯器會檢查出你輸入的字元是utf-8還是gbk,基本根據的就是這個utf-8模闆,如果符合模闆,就會判斷是utf-8。很多文章說的txt中輸入“聯通”存為gbk編碼再打開會出現亂碼就是這個原因導緻的。

還有一種ansi是什麼呢?windows核心是使用utf-16編寫的,但是頁面上展示的語言是根據系統設定的“語言”來展示的。ansi就是windows系統根據你設定的語言環境而進行自動變化的一種編碼。比如在中文windows系統下,ansi就代表gbk編碼,日文作業系統下就代表jis編碼。

繼續閱讀