從ASCII到UTF 8 字符集到底是什麼?

2021-09-11 11:17:20 字數 3049 閱讀 5143

這世界上大概有100萬個字元,平均每個人一生接觸的字元數在6k左右,那麼問題來了,如何讓計算機來存下所有的字元。

計算機誕生於美國,起初用的是真空管的電位高低來表示0和1,8個真空管為一組,由此組成了計算機內的單位——byte位元組,大小為8個bit。

美國人一生只需要識別26個字母就夠了。於是,他們用半個位元組就足以表示自己所能識別的字元。這就是ascii字符集,範圍為0-127.

其中,0x20以下為控制字元,不可顯示。比如,0x10表示換行,0x07表示發聲。另外還有個特殊的控制字元,0x7f表示刪除。

0x30表示數字0;0x41表示字母a;0x61表示字母a。

這個字符集佔的空間小,又足以滿足日常需求,美國人很滿意。

歐洲國家進口計算機後,也有了在計算機上顯示自己的常用字元的要求,於是乎,就想著對ascii進行擴充套件。

你美國人不是才用了半個位元組嗎,那好,剩下的半個位元組由我們來定義。

於是乎,0x80 - 0xff的定義就被填充成了希臘字母,羅馬字母等符號。

此時,編碼依舊控制在8位以內,相安無事。

古老的中國,終於也開始接觸計算機。它博大精深的文化,怕是ascii編碼的制定者所始料未及的。

美國人想到中國的鍵盤,怎麼著至少也得兩千多個鍵吧。

呵呵,區區乙個位元組,256個坑位,怎麼填的下我博大精深數千漢字字元呢。

於是,強大的**發布了自己的字元編碼標準——gb2312.

思想很簡單,如果乙個字元值為127及以下,那它就是乙個單位元組字元,和ascii相容; 如果乙個字元值為127以上,那它和後面的那個字元組成乙個漢字。(同時,後面那個字元也一定是127以上的)

通過這個方式,我們擴充套件出來了7000+的簡體漢字,同時還把日本假名,羅馬希臘字母,數學符號也容納了進來。

同時還產生了乙個新的概念,全形字符:ascii碼裡本身有的字元,也被我們擴充套件成了雙位元組字元。為了區分,前者稱為半形字元,後者稱為全形字符。

至此,中文也可以在計算機上表示了。

還是乙個中華文化博大精深的問題,7000個簡體漢字並不能把漢字窮舉了,一些生僻字並不包含在gb2312裡。

gb2312表示,我可能還可以搶救一下,我還有另一半的潛力沒有發揮呢!

這另一半的潛力就是,第二個位元組的0x00 - 0x7f部分。這部分空出來,是由於gb2312表示漢字時,要求兩個位元組都是在0x80 - 0xff範圍內的。

填上這部分的空檔之後,再生僻的字也被表示出來了,同時,我們還考慮到港澳台同胞的感受,包含了繁體字,一共大概增加了20k的漢字和符號。

從今以後,再也不許有人跟我說在計算機裡有打不出來的漢字~

然而,我們做出來的gbk,並不被對岸承認。因為對岸並沒有和我們共建這個標準。 隨著時間的推移,網際網路的興起,不止海峽兩岸,全世界範圍內共建乙個字符集的呼聲越來越高。

這個標準,只能有乙個機構可以做,那就是iso(我對這個組織的印象是它曾經弄出來了乙個教科書級別的網路七層模型,也僅限於教科書使用)。 iso作為乙個類似《聖經》中創世紀的角色,於是說了一句「要有unicode字符集」。 於是,就有了unicode字符集。

unicode,統一了所有地區的字元,且還在不斷擴充中。所有地區的字元,都被用兩個位元組來表示。與前面提到的gbk等不同的是,unicode並不相容ascii。它要求ascii字元在高8位補0,強行把ascii碼用兩個位元組來表示。

到這裡,世界在unicode的驅動下,似乎要趨於大同了。

叮咚~iso的門鈴響了,是美國人啦~

回到ascii的創始那一段,美國人用的最多的,還是26個字母,乙個位元組可以表示完的字符集,非要用我用兩個位元組來表示,我山姆大叔今天就是要逆你unicode的天。你知不知道你讓我的網路流量和硬碟儲存空間都翻倍啦?

加上一些只認ascii碼的老系統,根本就無法在unicode環境工作了。

這個時候,就需要乙個折中的方案出來了。既相容ascii,不造成空間浪費,又能像unicode那樣,囊括四海之內的字元。

這個時候,utf-8編碼被提出來了。

前面說的都是字符集,utf-8卻是一種編碼方式,因為它並不是去做字符集的事情,而是為的便於unicode碼的傳輸和儲存而生的。

與其他的編碼方式(如哈夫曼編碼)的思想一致,utf-8的原則就是,使用不定長位元組(1-6位元組)來表達乙個字元,使用頻率越高的字元,位元組數越少。這樣就能最大程度上節約空間。具體的編碼方式如下:

單位元組字元:

以0開頭,後面7位表示字元,事實上,utf-8的單位元組字元就是ascii字元,完美相容;

n位元組字元:

第乙個位元組的前n位為1,第n+1位為0。讀到此位元組時,可以方便的知道後續多少位元組是用來表示乙個字元;

其餘位元組,以10開頭。

複製**

unicode符號範圍 | utf-8編碼方式

(十六進製制) | (二進位制)

—————————————————————–

0000 0000-0000 007f | 0******x

0000 0080-0000 07ff | 110***xx 10******

0000 0800-0000 ffff | 1110***x 10****** 10******

0001 0000-0010 ffff | 11110*** 10****** 10****** 10******

複製**

utf-8和unicode是一一對應的,對於常用漢字,基本上都是占用3個位元組,生僻漢字可能占用到6個位元組。對於gb2312和gbk來講,utf-8無疑造成了浪費,所以,utf-8可以說是對英文友好,但對中文不友好的一種編碼方式。所以在中文界,gb2312與gbk依舊有自己的市場。

簡單來說:

美國人為了表示日常用的字元,制定了ascii。用乙個位元組來表達字元;

歐洲人為了表示日常用的字元,擴充了ascii。加入ascii擴充套件字元;用乙個位元組來表達字元;

中國人為了表示常用簡體漢字,制定了gb2312。用兩個位元組來表達字元;

中國人為了表示生僻漢字和繁體字,擴充gb2312為gbk。用兩個位元組來表達字元;

iso為了統一全世界的字元,制定了unicode。用兩個位元組來表達字元;

為的便於unicode的傳輸和儲存,utf-8編碼方式被制定出來。使用1-6個不定位元組來表達字元。

UTF 8字符集的學習

今天因為擷取中文字串的原因,查了下utf 8字符集的資料,發現之前記憶的知識點有誤,之前一直以為utf 8中英文是1個位元組,其他語言的字元是3個位元組,查完資料後才發現utf 8字符集是一種變長字符集,每個字元占用位元組從1個到6個不等,恰好英文本元使用1個位元組,中文字元使用3個位元組,而且還知...

tinyxml解析UTF 8字符集的xml

今天在程式中遇到,當通訊的xml裡面含有中文字元的時候,tinyxml解析時總是報錯,不能進行解析,查詢原因後發現是tinyxml在解析utf 8字符集的xml時,需要特殊指定字符集才行,下面是對於讀取檔案和直接解析字串所需的tinyxml函式的使用方式。一 需解析的xml 21 0全天侯模板 11...

mysql中的utf8字符集與標準UTF 8的區別

儘管字面上非常相似,但mysql的utf 8的覆蓋範圍僅僅是所有utf 8字符集的一部分。這非常容易誤導初學者。utf 8是ucs字符集的一種編碼方式,可能將乙個字元編碼為1個位元組,2個位元組,3個位元組,或者4個位元組。編碼為1個位元組的字元就是ascii碼 有時稱為latin文字元號 包含了拉...