Unicode 赃绊、 ASCII 榴徐、 GBK 守问、UTF-8 … 有沒有每次看到這些就有一種好像知道模糊的大概,但又不是特別清晰的感覺坑资?現(xiàn)在耗帕,我們就來一探究竟。
ASCII 碼
ASCII 字符是隨著計算機的發(fā)明而誕生袱贮,計算機最早是在美國開始使用仿便,當(dāng)時為了將生活中用到的各種文字和符號能夠通過計算機進行存儲、顯示和傳輸攒巍,人們就將控制字符嗽仪、空格、標(biāo)點符號柒莉、數(shù)字和大小寫字母進行編號闻坚,從編號 0 - 127 共 128 個字符。到了 1967 年兢孝,專門為這個方案起了一個名字叫 ASCII ( American Standard Code for Information Interchange 窿凤,美國信息交換標(biāo)準(zhǔn)代碼 )。
我們知道跨蟹,計算機內(nèi)部雳殊,所有信息最終都是一個二進制值。每一個二進制位(bit)有0和1兩種狀態(tài)窗轩,因此八個二進制位就可以組合出256種狀態(tài)夯秃,這被稱為一個字節(jié)(byte)。也就是說,一個字節(jié)一共可以用來表示256種不同的狀態(tài)寝并,每一個狀態(tài)對應(yīng)一個符號箫措,就是256個符號,從00000000到11111111衬潦。
上個世紀(jì)60年代,美國制定了一套字符編碼植酥,對英語字符與二進制位之間的關(guān)系镀岛,做了統(tǒng)一規(guī)定。這被稱為 ASCII 碼友驮,一直沿用至今漂羊。
ASCII 碼一共規(guī)定了128個字符的編碼,比如空格SPACE是32(二進制00100000)卸留,大寫的字母A是65(二進制01000001)走越。這128個符號(包括32個不能打印出來的控制符號),只占用了一個字節(jié)的后面7位耻瑟,最前面的一位統(tǒng)一規(guī)定為0旨指。
非 ASCII 編碼
英語用128個符號編碼就夠了,但是用來表示其他語言喳整,128個符號是不夠的谆构。比如,在法語中框都,字母上方有注音符號搬素,它就無法用 ASCII 碼表示。于是魏保,一些歐洲國家就決定熬尺,利用字節(jié)中閑置的最高位編入新的符號。比如谓罗,法語中的é的編碼為130(二進制10000010)粱哼。這樣一來,這些歐洲國家使用的編碼體系妥衣,可以表示最多256個符號皂吮。
但是,這里又出現(xiàn)了新的問題税手。不同的國家有不同的字母蜂筹,因此,哪怕它們都使用256個符號的編碼方式芦倒,代表的字母卻不一樣艺挪。比如,130在法語編碼中代表了é,在希伯來語編碼中卻代表了字母Gimel (?)麻裳,在俄語編碼中又會代表另一個符號口蝠。但是不管怎樣,所有這些編碼方式中津坑,0--127表示的符號是一樣的妙蔗,不一樣的只是128--255的這一段。
至于亞洲國家的文字疆瑰,使用的符號就更多了眉反,漢字就多達10萬左右。一個字節(jié)只能表示256種符號穆役,肯定是不夠的寸五,就必須使用多個字節(jié)表達一個符號。比如耿币,簡體中文常見的編碼方式是 GB2312梳杏,使用兩個字節(jié)表示一個漢字,所以理論上最多可以表示 256 x 256 = 65536 個符號淹接。
中文編碼的問題需要專文討論十性,這篇筆記不涉及。這里只指出蹈集,雖然都是用多個字節(jié)表示一個符號烁试,但是GB類的漢字編碼與后文的 Unicode 和 UTF-8 是毫無關(guān)系的。
Unicode
正如上一節(jié)所說拢肆,世界上存在著多種編碼方式减响,同一個二進制數(shù)字可以被解釋成不同的符號。因此郭怪,要想打開一個文本文件支示,就必須知道它的編碼方式,否則用錯誤的編碼方式解讀鄙才,就會出現(xiàn)亂碼颂鸿。為什么電子郵件常常出現(xiàn)亂碼?就是因為發(fā)信人和收信人使用的編碼方式不一樣攒庵。
可以想象嘴纺,如果有一種編碼,將世界上所有的符號都納入其中浓冒。每一個符號都給予一個獨一無二的編碼栽渴,那么亂碼問題就會消失。這就是 Unicode稳懒,就像它的名字都表示的闲擦,這是一種所有符號的編碼。
Unicode 當(dāng)然是一個很大的集合,現(xiàn)在的規(guī)氖洌可以容納100多萬個符號纯路。每個符號的編碼都不一樣,比如寞忿,U+0639表示阿拉伯字母Ain驰唬,U+0041表示英語的大寫字母A,U+4E25表示漢字嚴(yán)罐脊。具體的符號對應(yīng)表定嗓,可以查詢unicode.org,或者專門的漢字對應(yīng)表萍桌。
Unicode全稱為Unicode標(biāo)準(zhǔn)(The Unicode Standard),其官方機構(gòu)Unicode聯(lián)盟所用的中文名稱為統(tǒng)一碼[1]凌简,又譯作萬國碼上炎、統(tǒng)一字元碼、統(tǒng)一字符編碼[2]雏搂,是信息技術(shù)領(lǐng)域的業(yè)界標(biāo)準(zhǔn)藕施,其整理、編碼了世界上大部分的文字系統(tǒng)凸郑,使得電腦能以通用劃一的字符集來處理和顯示文字裳食,不但減輕在不同編碼系統(tǒng)間切換和轉(zhuǎn)換的困擾,更提供了一種跨平臺的亂碼問題解決方案芙沥。
Unicode 的問題
需要注意的是诲祸,Unicode 只是一個符號集,它只規(guī)定了符號的二進制代碼而昨,卻沒有規(guī)定這個二進制代碼應(yīng)該如何存儲救氯。
比如,漢字嚴(yán)的 Unicode 是十六進制數(shù)4E25歌憨,轉(zhuǎn)換成二進制數(shù)足足有15位(100111000100101)着憨,也就是說,這個符號的表示至少需要2個字節(jié)务嫡。表示其他更大的符號甲抖,可能需要3個字節(jié)或者4個字節(jié),甚至更多心铃。
這里就有兩個嚴(yán)重的問題准谚,第一個問題是,如何才能區(qū)別 Unicode 和 ASCII 于个?計算機怎么知道三個字節(jié)表示一個符號氛魁,而不是分別表示三個符號呢?第二個問題是,我們已經(jīng)知道秀存,英文字母只用一個字節(jié)表示就夠了捶码,如果 Unicode 統(tǒng)一規(guī)定,每個符號用三個或四個字節(jié)表示或链,那么每個英文字母前都必然有二到三個字節(jié)是0惫恼,這對于存儲來說是極大的浪費,文本文件的大小會因此大出二三倍澳盐,這是無法接受的祈纯。
它們造成的結(jié)果是:1)出現(xiàn)了 Unicode 的多種存儲方式,也就是說有許多種不同的二進制格式叼耙,可以用來表示 Unicode腕窥。2)Unicode 在很長一段時間內(nèi)無法推廣,直到互聯(lián)網(wǎng)的出現(xiàn)筛婉。
UTF-8
互聯(lián)網(wǎng)的普及簇爆,強烈要求出現(xiàn)一種統(tǒng)一的編碼方式。UTF-8 就是在互聯(lián)網(wǎng)上使用最廣的一種 Unicode 的實現(xiàn)方式爽撒。其他實現(xiàn)方式還包括 UTF-16(字符用兩個字節(jié)或四個字節(jié)表示)和 UTF-32(字符用四個字節(jié)表示)入蛆,不過在互聯(lián)網(wǎng)上基本不用。重復(fù)一遍硕勿,這里的關(guān)系是哨毁,UTF-8 是 Unicode 的實現(xiàn)方式之一。
UTF-8 最大的一個特點源武,就是它是一種變長的編碼方式扼褪。它可以使用1~4個字節(jié)表示一個符號,根據(jù)不同的符號而變化字節(jié)長度软能。
Unicode 符號表
https://symbl.cc/cn/unicode/table/#cjk-unified-ideographs-extension-a
https://www.cnblogs.com/csguo/p/7401874.html
https://ave-maria.gitee.io/banomo/code_unicode_table.html
中日韓漢字Unicode編碼表 http://www.chi2ko.com/tool/CJK.htm