計算機中的字元編碼與字符集的關係

2021-09-11 07:59:35 字數 3481 閱讀 8908

什麼是字符集

在介紹字符集之前,我們先了解下為什麼要有字符集。我們在計算機螢幕上看到的是實體化的文字,而在計算機儲存介質中存放的實際是二進位制的位元流。那麼在這兩者之間的轉換規則就需要乙個統一的標準,否則把我們的u盤查到老闆的電腦上文件就亂碼了,小夥伴qq上傳過來的檔案在我們本地開啟又亂碼了。(ps:這裡科普下亂碼的英文native說法是mojibake)。於是為了實現轉換標準,各種字符集標準就出現了。簡單的說字符集就規定了某個文字對應的二進位制數字存放方式(編碼)和某串二進位制數值代表了哪個文字(解碼)的轉換關係。

那麼為什麼會有那麼多字符集標準呢?這個問題實際非常容易回答。問問自己為什麼我們的插頭拿到英國就不能用了呢?為什麼顯示器同時有dvi,vga,hdmi,dp這麼多介面呢?很多規範和標準在最初制定時並不會意識到這將會是以後全球普適的準則,或者處於組織本身利益就想從本質上區別於現有標準。於是,就產生了那麼多具有相同效果但又不相互相容的標準了。

說了那麼多我們來看乙個實際例子,下面就是屌這個字在各種編碼下的十六進製制和二進位制編碼結果,怎麼樣有沒有一種很屌的感覺?

字符集 16進製制編碼

utf-8 0xe5b18c

utf-16 0x5c4c

gbk 0x8cc5

字元編碼方式

ascii碼

我們知道,計算機內部,所有資訊最終都是乙個二進位制值。每乙個二進位制位(bit)有0和1兩種狀態,因此八個二進位制位就可以組合出256種狀態,這被稱為乙個位元組(byte)。也就是說,乙個位元組一共可以用來表示256種不同的狀態,每乙個狀態對應乙個符號,就是256個符號,從00000000到11111111。

上個世紀60年代,美國制定了一套字元編碼,對英語字元與二進位制位之間的關係,做了統一規定。這被稱為 ascii 碼,一直沿用至今。

ascii 碼一共規定了128個字元的編碼,比如空格space是32(二進位制00100000),大寫的字母a是65(二進位制01000001)。這128個符號(包括32個不能列印出來的控制符號),只占用了乙個位元組的後面7位,最前面的一位統一規定為0。

非ascii碼

英語用128個符號編碼就夠了,但是用來表示其他語言,128個符號是不夠的。比如,在法語中,字母上方有注音符號,它就無法用 ascii 碼表示。於是,一些歐洲國家就決定,利用位元組中閒置的最高位編入新的符號。比如,法語中的é的編碼為130(二進位制10000010)。這樣一來,這些歐洲國家使用的編碼體系,可以表示最多256個符號。

但是,這裡又出現了新的問題。不同的國家有不同的字母,因此,哪怕它們都使用256個符號的編碼方式,代表的字母卻不一樣。比如,130在法語編碼中代表了é,在希伯來語編碼中卻代表了字母gimel (ג),在俄語編碼中又會代表另乙個符號。但是不管怎樣,所有這些編碼方式中,0–127表示的符號是一樣的,不一樣的只是128–255的這一段。

至於亞洲國家的文字,使用的符號就更多了,漢字就多達10萬左右。乙個位元組只能表示256種符號,肯定是不夠的,就必須使用多個位元組表達乙個符號。比如,簡體中文常見的編碼方式是 gb2312,使用兩個位元組表示乙個漢字,所以理論上最多可以表示 256 x 256 = 65536 個符號。

中文編碼的問題需要專文討論,這篇筆記不涉及。這裡只指出,雖然都是用多個位元組表示乙個符號,但是gb類的漢字編碼與後文的 unicode 和 utf-8 是毫無關係的。

unicode

正如上一節所說,世界上存在著多種編碼方式,同乙個二進位制數字可以被解釋成不同的符號。因此,要想開啟乙個文字檔案,就必須知道它的編碼方式,否則用錯誤的編碼方式解讀,就會出現亂碼。為什麼電子郵件常常出現亂碼?就是因為發信人和收信人使用的編碼方式不一樣。

可以想象,如果有一種編碼,將世界上所有的符號都納入其中。每乙個符號都給予乙個獨一無二的編碼,那麼亂碼問題就會消失。這就是 unicode,就像它的名字都表示的,這是一種所有符號的編碼。

unicode 當然是乙個很大的集合,現在的規模可以容納100多萬個符號。每個符號的編碼都不一樣,比如,u+0639表示阿拉伯字母ain,u+0041表示英語的大寫字母a,u+4e25表示漢字嚴。具體的符號對應表,可以查詢unicode.org,或者專門的漢字對應表。

需要注意的是,unicode 只是乙個符號集,它只規定了符號的二進位制**,卻沒有規定這個二進位制**應該如何儲存。

比如,漢字嚴的 unicode 是十六進製制數4e25,轉換成二進位制數足足有15位(100111000100101),也就是說,這個符號的表示至少需要2個位元組。表示其他更大的符號,可能需要3個位元組或者4個位元組,甚至更多。

這裡就有兩個嚴重的問題,第乙個問題是,如何才能區別 unicode 和 ascii ?計算機怎麼知道三個位元組表示乙個符號,而不是分別表示三個符號呢?第二個問題是,我們已經知道,英文本母只用乙個位元組表示就夠了,如果 unicode 統一規定,每個符號用三個或四個位元組表示,那麼每個英文本母前都必然有二到三個位元組是0,這對於儲存來說是極大的浪費,文字檔案的大小會因此大出二三倍,這是無法接受的。

它們造成的結果是:1)出現了 unicode 的多種儲存方式,也就是說有許多種不同的二進位制格式,可以用來表示 unicode。2)unicode 在很長一段時間內無法推廣,直到網際網路的出現。

utf-8

網際網路的普及,強烈要求出現一種統一的編碼方式。utf-8 就是在網際網路上使用最廣的一種 unicode 的實現方式。其他實現方式還包括 utf-16(字元用兩個位元組或四個位元組表示)和 utf-32(字元用四個位元組表示),不過在網際網路上基本不用。重複一遍,這裡的關係是,utf-8 是 unicode 的實現方式之一。

utf-8 最大的乙個特點,就是它是一種變長的編碼方式。它可以使用1~4個位元組表示乙個符號,根據不同的符號而變化位元組長度。

utf-8 的編碼規則很簡單,只有二條:

1)對於單位元組的符號,位元組的第一位設為0,後面7位為這個符號的 unicode 碼。因此對於英語字母,utf-8 編碼和 ascii 碼是相同的。

2)對於n位元組的符號(n > 1),第乙個位元組的前n位都設為1,第n + 1位設為0,後面位元組的前兩位一律設為10。剩下的沒有提及的二進位制位,全部為這個符號的 unicode 碼。

字符集只是乙個規則集合的名字,

字符集 = 字型檔表(character repertoire)、編碼字符集(coded character set)、字元編碼(character encoding form)。

2、字型檔表:

字型檔表是乙個相當於所有可讀或者可顯示字元的資料庫,字型檔表決定了整個字符集能夠展現表示的所有字元的範圍。

3、編碼字符集:(簡稱字符集,如unicode、ascii)

編碼字符集,用乙個編碼值code point來表示乙個字元(即該字元在子庫表中的位置),這個值稱為字元對應於編碼字符集(如:unicode、ascii)的序號。

4、字元編碼:

字元編碼,是編碼字符集和實際儲存數值之間的轉換關係。字元,是根據字元編碼方案轉換為乙個二進位制數值儲存在計算機中的。

所以,字元編碼是定義在字符集上的對映規則。(字元-------->計算機中的實際儲存值)

注意:編碼字符集unicode,有utf-8、utf-16、utf-32等多種字元編碼

編碼字符集ascii,本身就是編碼字符集,又是字元編碼

編碼字符集cb2312,只有euc-cn一種字元編碼

計算機中的字元編碼

計算機中的字元編碼 ascii 美國資訊交換標準 american standard code for information interchange 基於拉丁字母的一套電腦編碼系統。它主要用於顯示現代英語和其他西歐語言。它是現今最通用的單位元組編碼系統。gb2312 國標2312編碼,單雙位元組編...

關於計算機字符集編碼

頁是字符集編碼的別名,也有人稱 程式碼頁 早期,頁是ibm稱呼電腦bios本身支援的字符集編碼的名稱。當時通用的作業系統都是命令列介面系統,這些作業系統直接使用bios 的vga功能來顯示字元,作業系統的編碼支援也就依靠bios的編碼。現在這bios 頁被稱為oem 頁。圖形作業系統解決了此問題,圖...

計算機中的編碼

ascii 英文編碼,用乙個位元組 0 255 表示英文本元 gb2312 漢字編碼,用兩個位元組表示中文漢字,同時相容英文 多餘的部分用0補足 但是其他國家的文字都有自己的編碼方式,當不同國家的文字在一起時不能相容,此時出現了unicode編碼 但是unicode編碼在表示英文本元時會浪費一倍的儲...