天天看點

字元編碼(ASCII,Unicode和UTF-8,GBK)一.ASCII碼二.Unicode三.GBK

一.ASCII碼

1.1ASCII碼是什麼:

ASCII(American Standard Code for Information Interchange:美國資訊交換标準代碼)是基于拉丁字母的一套電腦編碼系統,主要用于顯示現代英語和其他西歐語言。

1.2解釋幾個概念

bit(比特):表示資訊的最小機關,二進制中一位(bit)隻有兩種狀态0或者1。

byte(位元組):八個二進制位(bit)組成一個位元組,一個位元組有2的8次方(256)種狀态。不同的狀态用來表示不同的字元。

1.3英語的128個

對于英語來說,因為其所有文字都可以使用26個字母來組合表示,再加上數字,計算機中的控制符等128個就夠用了。

計算機内部,所有的資訊最終都表示為一個二進制的字元串,上個世紀60年代,美國制定了一套字元編碼,對英語字元與二進制位之間的關系,做了統一規定。這被稱為ASCII碼,一直沿用至今。

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

1.4ASCII碼的局限性

英語用128個符号編碼就夠了,但是用來表示其他語言,128個符号是不夠的。比如,在法語中,字母上方有注音符号,它就無法用ASCII碼表示。于是,一些歐洲國家就決定,利用位元組中閑置的最高位編入新的符号。比如,法語中的é的編碼為130(二進制10000010)。這樣一來,這些歐洲國家使用的編碼體系,可以表示最多256個符号。但是,這裡又出現了新的問題。不同的國家有不同的字母,是以,哪怕它們都使用256個符号的編碼方式,代表的字母卻不一樣。比如,130在法語編碼中代表了é,在希伯來語編碼中卻代表了字母Gimel (ג),在俄語編碼中又會代表另一個符号。但是不管怎樣,所有這些編碼方式中,0–127表示的符号是一樣的,不一樣的隻是128–255的這一段。至于亞洲國家的文字,使用的符号就更多了,漢字就多達10萬左右。一個位元組隻能表示256種符号,肯定是不夠的,就必須使用多個位元組表達一個符号。比如,簡體中文常見的編碼方式是GB2312,使用兩個位元組表示一個漢字,是以理論上最多可以表示256x256=65536個符号。

二.Unicode

2.1大一統的Unicode

世界上有多重編碼方式,同一個二進制數字可以被解釋成不同的符号。

同一個文本檔案如果不知道它的編碼方式,使用錯誤的編碼方式打開,那麼就會出現亂碼。我們迫切的需要一種統一的編碼方式,

這就是Unicode。

Unicode當然是一個很大的集合,現在的規模可以容納100多萬個符号。每個符号的編碼都不一樣。

2.2Unicode存在的問題

需要注意的是,Unicode隻是一個符号集,它隻規定了符号的二進制代碼,卻沒有規定這個二進制代碼應該如何存儲。

舉個例子:

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

産生的問題

第一個問題是,如何才能差別Unicode和ASCII?計算機怎麼知道三個位元組表示一個符号,而不是分别表示三個符号呢?

第二個問題是,我們已經知道,英文字母隻用一個位元組表示就夠了,如果Unicode統一規定,每個符号用三個或四個位元組表示,那麼每個英文字母前都必然有二到三個位元組是0,這對于存儲來說是極大的浪費,文本檔案的大小會是以大出二三倍,這是無法接受的。

産生的結果

第一,出現了Unicode的多種存儲方式,也就是說有許多種不同的二進制格式,可以用來表示Unicode。

第二,Unicode在很長一段時間内無法推廣,直到網際網路的出現。

2.3UTF-8

UTF-8是Unicode的實作方式之一,在網際網路上使用最廣的一種Unicode的實作方式。其他實作方式還包括UTF-16(字元用兩個位元組或四個位元組表示)和UTF-32(字元用四個位元組表示),不過在網際網路上基本不用。

特點

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

UTF-8的編碼規則

  1. 對于單位元組的符号,位元組的第一位設為0,後面7位為這個符号的unicode碼。是以對于英語字母,UTF-8編碼和ASCII碼是相同的。
  2. 對于n位元組的符号(n>1),第一個位元組的前n位都設為1,第n+1位設為0,後面位元組的前兩位一律設為10。剩下的沒有提及的二進制位,全部為這個符号的unicode碼。

示例編碼規則

下表總結了編碼規則,字母x表示可用編碼的位。

Unicode符号範圍(十六進制) UTF-8編碼方式(二進制)
0000 0000-0000 007F 0xxxxxxx
0000 0080-0000 07FF 110xxxxx 10xxxxxx
0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

參照上表,解讀UTF-8編碼非常簡單。如果一個位元組的第一位是0,則這個位元組單獨就是一個字元;如果第一位是1,則連續有多少個1,就表示目前字元占用多少個位元組。

具體示例

下面,還是以漢字"嚴"為例,示範如何實作UTF-8編碼。

已知"嚴"的unicode是4E25(100111000100101),根據上表,可以發現4E25處在第三行的範圍内(0000 0800-0000 FFFF),是以"嚴"的UTF-8編碼需要三個位元組,即格式是"1110xxxx 10xxxxxx 10xxxxxx"。然後,從"嚴"的最後一個二進制位開始,依次從後向前填入格式中的x,多出的位補0。這樣就得到了,“嚴"的UTF-8編碼是"11100100 10111000 10100101”,轉換成十六進制就是E4B8A5。

三.GBK

GBK全稱《漢字内碼擴充規範》(GBK即“國标”、“擴充”漢語拼音的第一個字母,英文名稱:Chinese Internal Code Specification) ,我們國家針對漢字的編碼标準。

繼續閱讀