?? Hi束析,我是小余毛好。 本文已收錄到 GitHub · Androider-Planet 中。這里有 Android 進(jìn)階成長(zhǎng)知識(shí)體系断楷,關(guān)注公眾號(hào) [小余的自習(xí)室] ,在成功的路上不迷路!
前言
你是不是工作了很多年了衣厘,一直沒(méi)搞清楚計(jì)算機(jī)中的各種編碼規(guī)則,雖然平時(shí)都會(huì)使用压恒,但是內(nèi)部機(jī)制原理一直都是之其然而不知其所以然影暴,開(kāi)發(fā)中也會(huì)經(jīng)常涉及到這塊內(nèi)容,但都沒(méi)有太多重視探赫,這可能會(huì)讓有吃一些虧(出項(xiàng)目bug了)型宙,本著追本溯源的精神或是為了讓自己在少出血bug,小余今天就來(lái)聊聊這塊內(nèi)容伦吠。
目錄
1.字符集與字符編碼
首先要明確兩概念妆兑,字符集(charset)和字符編碼(encoding)。
字符集
字符集顧名思義:很多字符的集合毛仪。這些字符組成一套字符系統(tǒng)搁嗓,用來(lái)表達(dá)我們生活中各種含義,
比如0~9以及各種加減法等符號(hào)的集合箱靴,可以表示生活中的“數(shù)字集合”腺逛,不然1+1是什么計(jì)算機(jī)可不知道? 26個(gè)大小寫英文字母加上標(biāo)點(diǎn)符號(hào)就組成了“英文字符集“刨晴,這些字符集在英美人看來(lái)就組成了一套符號(hào)系統(tǒng)屉来,看到”I Love you“就知道什么意思了路翻。 再比如我們新華字典中的所有漢字加上標(biāo)點(diǎn)符號(hào)就組成了“中文字符集”,這個(gè)字符集就組成了中文文字系統(tǒng)茄靠∶酰看到“我愛(ài)你”也就知道什么意思了,可以對(duì)于不懂中文的老外來(lái)慨绳,因?yàn)闆](méi)有中文字符集掉冶,看到“我愛(ài)你”可就一臉懵逼了。
字符編碼
字符編碼:言外之意就是對(duì)字符進(jìn)行編碼脐雪,那為什么要對(duì)字符編碼厌小,其實(shí)字符編碼最終目的就是為了存儲(chǔ)或者傳輸。我們的計(jì)算機(jī)最早是用來(lái)提供算術(shù)功能的战秋,和算盤功能類似璧亚,但是后來(lái)發(fā)現(xiàn)計(jì)算機(jī)可以做很多事情。 其中就包括存儲(chǔ)機(jī)制脂信,如何存儲(chǔ)呢癣蟋?假設(shè)“LOVE”這個(gè)單詞,我們使用數(shù)字1代表L狰闪,數(shù)字2代表O疯搅,數(shù)字3代表V,數(shù)字4代表E埋泵,將1234存儲(chǔ)在某個(gè)區(qū)域幔欧,這樣就可以知道這4個(gè)數(shù)字代表了“LOVE”,當(dāng)然實(shí)際LOVE有自己的字符表示丽声,這里使用1234作為例講解礁蔗。
字符編碼的四個(gè)步驟
要在計(jì)算機(jī)中建立一個(gè)“字符編碼模型”,需要四個(gè)步驟:
- 1.要有一個(gè)字符庫(kù)恒序,確定這些字符庫(kù)足夠表意瘦麸。比如ASCII字符集,已經(jīng)足夠表示英文系統(tǒng)歧胁,但是不能表達(dá)中文滋饲,于是有了GB2312字符集。
- 2.第一層編碼:給每個(gè)字符選個(gè)數(shù)字(Code Point)喊巍,比如ASCII碼中屠缭,用65表示“A”,97表示“a”。
- 3.第二層編碼:確定表示字符的二進(jìn)制位數(shù)(8位崭参,16位呵曹,32位)。ASCII碼使用7位來(lái)表示,因?yàn)楫?dāng)時(shí)制定者覺(jué)得7位以及夠用了奄喂,DBCS(雙字節(jié)字符集)使用了16位铐殃。
- 4.第三層編碼: 確定字符的二進(jìn)制存儲(chǔ)方式(大端還是小端)。比如X86機(jī)器使用小端跨新。
一個(gè)字符一般只有一種編碼格式富腊,當(dāng)字符集中的字符不夠用時(shí),會(huì)增加一些新的字符域帐,使用新的字符編碼格式赘被,形成新的字符集。所以有時(shí)候字符集和字符編碼的概念是很模糊的肖揣,并不嚴(yán)格區(qū)分民假。比如ASCII碼既可以成為一段“字符集”,也可以稱為一種“編碼格式”龙优。
也有一些字符集有多種編碼格式:如Unicode羊异,其中UTF-8和UTF-16等都是其編碼格式,這個(gè)后面是詳細(xì)講解彤断。
2.常用計(jì)算機(jī)編碼
1.ASCII碼
ASCII碼全稱“American Standard Code for Information Interchange”球化,美國(guó)標(biāo)準(zhǔn)信息交互碼,由美國(guó)標(biāo)準(zhǔn)委員會(huì)(American Standards Association瓦糟,簡(jiǎn)稱ASA)制定,后來(lái)該協(xié)會(huì)改組為“美國(guó)國(guó)家標(biāo)準(zhǔn)學(xué)會(huì)”(American National Standard Institute , 簡(jiǎn)稱ANSI )赴蝇,所以很多資料上說(shuō)ASCII碼是由ANSI指定的。
ASCII碼是從電報(bào)碼發(fā)展過(guò)來(lái)的,最早使用在7-bits電傳打印機(jī)上淆九。1960年纹安,ASA將ASCII標(biāo)準(zhǔn)化,于1963年發(fā)布第一版考余,1967年再發(fā)布一次大的版本先嬉,這個(gè)標(biāo)準(zhǔn)版本,也是一個(gè)7-bit碼楚堤,包含33個(gè)非打印字符(現(xiàn)在許多已經(jīng)廢棄了)疫蔓,95個(gè)打印字符(包含空格符),編碼范圍為0~127身冬。
然而ASCII碼只是美國(guó)的標(biāo)準(zhǔn)衅胀,對(duì)于其他國(guó)家,如中文酥筝,日文滚躯,韓文等大多使用的是象形文字,127個(gè)字符遠(yuǎn)遠(yuǎn)無(wú)法表達(dá)中國(guó)的漢字文化,于是各國(guó)在ASCII的基礎(chǔ)上制定了自己的字符集掸掏,但是本質(zhì)上都兼容ASCII茁影,如中國(guó)大陸的GK2312,臺(tái)灣省的(Big5)小日子的JIS等編碼規(guī)范丧凤。
2.EASCII
其實(shí)標(biāo)準(zhǔn)的ASCII就是7-bit的編碼(8字節(jié)募闲,但是最高位沒(méi)有編碼),后來(lái)使用過(guò)程中發(fā)現(xiàn)127個(gè)字符有點(diǎn)不夠用息裸,于是將ASCII進(jìn)行了擴(kuò)展蝇更,叫做EASCII或者h(yuǎn)igh-ASCII,8位的呼盆,能表示256個(gè)字符年扩。
由于不同的應(yīng)用場(chǎng)景,有不同的編碼访圃,有IBM的Extend ASCII和ANSI的Extend ASCII厨幻。 去wikipedia上會(huì)發(fā)現(xiàn)有好多種ASCII的標(biāo)準(zhǔn),大類就是IBM和ANSI(Windows的腿时,微軟很強(qiáng)勢(shì)况脆,ANSI的東西感覺(jué)就是給他們家用的)兩種,其實(shí)都是為了給自家系統(tǒng)用的批糟,隨著IBM操作系統(tǒng)的墜落格了,IBM的擴(kuò)展ASCII也根本上淡出視野。
擴(kuò)展的ASCII的產(chǎn)生
搭載Windows系統(tǒng)的計(jì)算機(jī)進(jìn)入歐洲之后徽鼎,發(fā)現(xiàn)標(biāo)準(zhǔn)的ASCII并不能滿足歐洲這些拉丁語(yǔ)族國(guó)家的語(yǔ)言表意盛末,決定對(duì)其進(jìn)行擴(kuò)展。同為印歐語(yǔ)系否淤,發(fā)現(xiàn)擴(kuò)展起來(lái)也沒(méi)那么難悄但,總共256個(gè)值就包括所有了。只需要將原來(lái)的7-bit擴(kuò)展為8-bit石抡,將原來(lái)的標(biāo)準(zhǔn)ASCII保留檐嚣,第一位使用0來(lái)表示。將擴(kuò)展的字符第一位使用1來(lái)表示
擴(kuò)展ASCII的組成
具體來(lái)講啰扛,擴(kuò)展后的ASCII碼表可以看成由三部分組成:
- 第一部分:由00H到1FH共32個(gè),一般用來(lái)通訊或作為控制之用嚎京。有些可以顯示在屏幕上,有些則不能顯示,但能看到其效果(如換行、退格)
- 第二部分:是由20H到7FH共96個(gè),這95個(gè)字符是用來(lái)表示阿拉伯?dāng)?shù)字侠讯、英文字母大小寫和下劃線挖藏、括號(hào)等符號(hào),都可以顯示在屏幕上.
- 第三部分:由80H到0FFH共128個(gè)字符,一般稱為"擴(kuò)充字符",這128個(gè)擴(kuò)充字符是由IBM制定的,并非標(biāo)準(zhǔn)的ASCII碼.這些字符是用來(lái)表示框線、音標(biāo)和其它歐洲非英語(yǔ)系的字母厢漩。
3.ISO-8859
由于每個(gè)國(guó)家以及公司對(duì)編碼的各自定制化膜眠,導(dǎo)致同一個(gè)字符在不同電腦之間由于編碼的不一致,顯示的結(jié)果也不一樣,現(xiàn)象就是亂碼宵膨。 那為了解決這個(gè)問(wèn)題架谎,ISO組織統(tǒng)一了一套標(biāo)準(zhǔn)的字符集。
與ASCII辟躏、EASCII字符編碼方案只包括單個(gè)獨(dú)立的字符集不同谷扣,ISO/IEC 8859字符編碼方案包括了一組字符集, 或者說(shuō)ISO/IEC 8859相當(dāng)于是一組字符集的總稱捎琐,其內(nèi)共包含了15個(gè)字符集会涎, 即ISO/IEC 8859-n,n=1瑞凑、2末秃、3...15、16籽御,其中12未定義练慕,所以實(shí)際上共15個(gè)。
這15個(gè)字符集技掏,大致上包括了歐洲各國(guó)所使用到的字符(甚至還包括一些外來(lái)語(yǔ)字符)铃将,而且每一個(gè)字符集的補(bǔ)充擴(kuò)展部分(即除了兼容ASCII字符之外的部分),都只實(shí)際使用了0xA00xFF(十進(jìn)制為160255)這96個(gè)編碼哑梳,而0x800x9F(十進(jìn)制為128159)這32個(gè)編碼并未實(shí)際定義字符劲阎。
其中,目前使用得最為普遍的是ISO/IEC 8859-1字符集鸠真,收錄了西歐常用字符(包括德法兩國(guó)的字母)哪工。
ISO/IEC 8859-1往往簡(jiǎn)稱為ISO 8859-1,而且還有一個(gè)稱之為L(zhǎng)atin-1(也寫作Latin1)的別名弧哎,即:ISO/IEC 8859-1 = ISO 8859-1 = Latin-1 = Latin1。
從ISO 8859-1到ISO 8859-16各自所收錄的字符分別如下:
ISO/IEC 8859-1 (Latin-1) - 西歐語(yǔ)言
ISO/IEC 8859-2 (Latin-2) - 中歐語(yǔ)言
ISO/IEC 8859-3 (Latin-3) - 南歐語(yǔ)言稚虎。世界語(yǔ)也可用此字符集顯示撤嫩。
ISO/IEC 8859-4 (Latin-4) - 北歐語(yǔ)言
ISO/IEC 8859-5 (Cyrillic) - 斯拉夫語(yǔ)言
ISO/IEC 8859-6 (Arabic) - 阿拉伯語(yǔ)
ISO/IEC 8859-7 (Greek) - 希臘語(yǔ)
ISO/IEC 8859-8 (Hebrew) - 希伯來(lái)語(yǔ)(視覺(jué)順序)
ISO 8859-8-I - 希伯來(lái)語(yǔ)(邏輯順序)
ISO/IEC 8859-9(Latin-5 或 Turkish)- 它把Latin-1的冰島語(yǔ)字母換走,加入土耳其語(yǔ)字母蠢终。
ISO/IEC 8859-10(Latin-6 或 Nordic)- 北日耳曼語(yǔ)支序攘,用來(lái)代替Latin-4。
ISO/IEC 8859-11 (Thai) - 泰語(yǔ)寻拂,從泰國(guó)的 TIS620 標(biāo)準(zhǔn)字集演化而來(lái)程奠。
ISO/IEC 8859-13(Latin-7 或 Baltic Rim)- 波羅的語(yǔ)族
ISO/IEC 8859-14(Latin-8 或 Celtic)- 凱爾特語(yǔ)族
ISO/IEC 8859-15 (Latin-9) - 西歐語(yǔ)言,加入Latin-1欠缺的芬蘭語(yǔ)字母和大寫法語(yǔ)重音字母祭钉,以及歐元(€)符號(hào)瞄沙。
ISO/IEC 8859-16 (Latin-10) - 東南歐語(yǔ)言。主要供羅馬尼亞語(yǔ)使用,并加入歐元符號(hào)距境。
4.MBCS申尼、DBCS
前面說(shuō)的ASCII,EASCII垫桂,ISO-8859中的每個(gè)字符使用的是8-bits表示的师幕,所以稱為“單字節(jié)字符集”(Single-Byte Character Set,簡(jiǎn)稱SBCS)诬滩。
但是到了亞洲霹粥,如中,日疼鸟,韓等國(guó)家每個(gè)文字就是一個(gè)字符后控,對(duì)于單字節(jié)的字符集來(lái),遠(yuǎn)遠(yuǎn)放不下了愚臀,于是亞洲國(guó)家制定了自己的字符集“多字節(jié)字符集” (Multi-Bytes Character Sets忆蚀,簡(jiǎn)稱MBCS)
windows 系統(tǒng)中,本地字符集就是MBCS姑裂,不過(guò)由于大部分字符是2字節(jié)的馋袜,所以又稱為“雙字節(jié)字符集”(Double-Bytes Character Sets,簡(jiǎn)稱DBCS)舶斧,所以有的時(shí)候看到MBCS欣鳖、DBCS,都是一回事茴厉。MBCS是完全兼容標(biāo)準(zhǔn)ASCII碼的泽台。
5.GB2312、GBK矾缓、
當(dāng)計(jì)算機(jī)被引入中國(guó)后怀酷,相關(guān)部門設(shè)計(jì)了GB系列規(guī)范(GB為國(guó)家的拼音縮寫)。按照GB系列編碼方案嗜闻,在一段文本中蜕依,如果一個(gè)字節(jié)是0~127,那么這個(gè)字節(jié)的含義與ASCII編碼相同琉雳,否則样眠,這個(gè)字節(jié)和下一個(gè)字節(jié)共同組成漢字(或是GB編碼定義的其他字符)。因此翠肘,GB系列編碼方案向下完全直接兼容ASCII編碼方案檐束。也就是說(shuō),如果當(dāng)前文本中使用的字符全是ASCII中的字符束倍,則其GB編碼和ASCII編碼是完成一樣的被丧。
GB2312是最早的GB編碼格式盟戏,收入了不足一萬(wàn)個(gè)漢字,基本能滿足日常需求晚碾,但是中國(guó)文件可是博大精深抓半,區(qū)區(qū)一萬(wàn)字肯定無(wú)法滿足,于是又在GB2312基礎(chǔ)上進(jìn)行了擴(kuò)展格嘁,擴(kuò)展后的編碼方案稱之為GBK(K是擴(kuò)的拼音縮寫)笛求,后來(lái)又在GBK的基礎(chǔ)上擴(kuò)了GB18030編碼方案,增加了一些少數(shù)名族的文字糕簿,一些生僻字被編到4個(gè)字節(jié)探入。
GB2312,GBK懂诗,GB18030(不包括GB13000)每次擴(kuò)展都會(huì)完全兼容前一個(gè)版本蜂嗽。這里要指出,雖然都用多個(gè)字節(jié)表示一個(gè)字符殃恒,但是GB類的漢字編碼與后文的Unicode編碼方案的UTF-8植旧、UTF-16、UTF-32等字符編碼方式是毫無(wú)關(guān)系的
不過(guò)离唐,也正因?yàn)椴坏貌皇褂枚鄠€(gè)字節(jié)來(lái)表示一個(gè)字符病附,相較于只使用單個(gè)字節(jié)的ASCII編碼方案,GB系列編碼方案與后面要介紹的Unicode編碼方案一樣亥鬓,無(wú)疑導(dǎo)致了更高的復(fù)雜度(包括時(shí)間復(fù)雜度完沪、空間復(fù)雜度等)。
比如嵌戈,當(dāng)多字節(jié)字符與原先的ASCII字符混用時(shí):
- 1)要么將原先的ASCII字符重新編碼為多個(gè)字節(jié)表示覆积,以便與其他多字節(jié)字符統(tǒng)一起來(lái)(UTF-16、UTF-32等采用的就是這種方法)熟呛;
- 2)要么保持ASCII字符為單個(gè)字節(jié)編碼不變宽档,但將其他多字節(jié)字符編碼中的各個(gè)字節(jié)的最高位(即首位)設(shè)為1,以避免與字節(jié)最高位為0的ASCII編碼相沖突(GB庵朝、UTF-8等采用的就是這種方法) 雌贱。
前者具有更高的空間復(fù)雜度,因?yàn)樵戎恍枰獑蝹€(gè)字節(jié)表示的ASCII字符偿短,現(xiàn)在也必須用多個(gè)字節(jié)來(lái)表示,顯然更為耗費(fèi)存儲(chǔ)空間馋没;后者則具有更高的時(shí)間復(fù)雜度昔逗,因?yàn)闉榱吮苊鉀_突以及其他種種考慮(比如擴(kuò)展性、容錯(cuò)性等)篷朵,使用了更為復(fù)雜的編碼算法(Encoding Algorithm)勾怒,無(wú)疑更為耗費(fèi)計(jì)算時(shí)間婆排。
GB2312
GB2312編碼方案,即《信息交換用漢字編碼字符集——基本集》笔链,是由中國(guó)國(guó)家標(biāo)準(zhǔn)總局于1980年發(fā)布段只、1981年5月1日開(kāi)始實(shí)施的一套國(guó)家標(biāo)準(zhǔn),標(biāo)準(zhǔn)號(hào)為GB2312-1980鉴扫。
GB2312編碼適用于漢字處理赞枕、漢字通信等系統(tǒng)之間的信息交換,通行于中國(guó)大陸坪创;新加坡等地也采用此編碼炕婶。中國(guó)大陸幾乎所有的中文系統(tǒng)和國(guó)際化的軟件都支持GB2312。
GB2312編碼為了兼容ASCII碼莱预,所有的編碼的字節(jié)都是從0x7F之后開(kāi)始的柠掂,一個(gè)漢字使用兩字節(jié)來(lái)表示,一個(gè)高字節(jié)一個(gè)低字節(jié)依沮,如果一個(gè)字節(jié)的小余0x7F的值涯贞,則表示的是一個(gè)ASCII碼值。
雖然GB2312完全兼容ASCII碼危喉,但是其并不兼容其他擴(kuò)碼宋渔,如EASCII。
GB2312標(biāo)準(zhǔn)共收錄6763個(gè)漢字姥饰,其中一級(jí)漢字3755個(gè)傻谁,二級(jí)漢字3008個(gè);同時(shí)列粪,除了漢字审磁,GB2312還收錄了包括拉丁字母、希臘字母岂座、日文平假名及片假名字符态蒂、俄語(yǔ)西里爾字母在內(nèi)的682個(gè)字符。
可能是處于美觀的考慮费什,除了漢字外的682個(gè)字符中钾恢,包括ASCII里本來(lái)就有的數(shù)字、標(biāo)點(diǎn)鸳址、字母等字符瘩蚪,又再次編寫了兩字長(zhǎng)的GB2312版本。 這682個(gè)雙字節(jié)編碼字符就是常說(shuō)的“全角”字符稿黍,而這些字符所對(duì)應(yīng)的單字節(jié)編碼的ASCII字符就被稱之為“半角”字符疹瘦。
全角、半角
全角字符是中文顯示及雙字節(jié)中文編碼的歷史遺留問(wèn)題巡球。
早期的點(diǎn)陣顯示器上由于像素有限言沐,原先ASCII西文字符的顯示寬度(比如8像素的寬度)用來(lái)顯示漢字有些捉襟見(jiàn)肘(實(shí)際上早期的針式打印機(jī)在打印輸出時(shí)也存在這個(gè)問(wèn)題)邓嘹,因此就采用了兩倍于ASCII字符的顯示寬度(比如16像素的寬度)來(lái)顯示漢字。
這樣一來(lái)险胰,ASCII西文字符在顯示時(shí)其寬度為漢字的一半汹押。或許是為了在西文字符與漢字混合排版時(shí)起便,讓西文字符能與漢字對(duì)齊等視覺(jué)美觀上的考慮棚贾,于是就設(shè)計(jì)了讓西文字母、數(shù)字和標(biāo)點(diǎn)等特殊字符在外觀視覺(jué)上也占用一個(gè)漢字的視覺(jué)空間(主要是寬度)缨睡,并且在內(nèi)部存儲(chǔ)上也同漢字一樣使用2個(gè)字節(jié)進(jìn)行存儲(chǔ)的方案鸟悴。這些與漢字在顯示寬度上一樣的西文字符就被稱之為全角字符。
而原來(lái)ASCII中的西文字符由于在外觀視覺(jué)上僅占用半個(gè)漢字的視覺(jué)空間(主要是寬度)奖年,并且在內(nèi)部存儲(chǔ)上使用1個(gè)字節(jié)進(jìn)行存儲(chǔ)细诸,相對(duì)于全角字符,因而被稱之為半角字符陋守。
后來(lái)震贵,其中的一些全角字符因?yàn)楸容^有用,就得到了廣泛應(yīng)用(比如全角的逗號(hào)“水评,”猩系、問(wèn)號(hào)“?”中燥、感嘆號(hào)“寇甸!”、空格“ ”等疗涉,這些字符在輸入法中文輸入狀態(tài)下的半角與全角是一樣的拿霉,英文輸入狀態(tài)下全角跟中文輸入狀態(tài)一樣,但半角大約為全角的二分之一寬)咱扣,專用于中日韓文本绽淘,成為了標(biāo)準(zhǔn)的中日韓標(biāo)點(diǎn)字符。而其它的許多全角字符則逐漸失去了價(jià)值(現(xiàn)在很少需要讓純文本的中文和西文字符對(duì)齊了)闹伪,就很少再用了沪铭。
現(xiàn)在全球字符編碼的事實(shí)標(biāo)準(zhǔn)是Unicode字符集及基于此的UTF-8、UTF-16等編碼實(shí)現(xiàn)方式偏瓤。Unicode吸納了許多遺留(legacy)編碼杀怠,并且為了兼容性而保留了所有字符。因此中文編碼方案中的這些全角字符也保留下來(lái)了厅克,而國(guó)家標(biāo)準(zhǔn)也仍要求字體和軟件都支持這些全角字符赔退。
不過(guò),半角和全角字符的關(guān)系在UTF-8已骇、UTF-16等中不再是簡(jiǎn)單的1字節(jié)和2字節(jié)的關(guān)系了离钝。具體參見(jiàn)后文。
GBK
GB2312-1980共收錄6763個(gè)漢字褪储,覆蓋了中國(guó)大陸99.75%的使用頻率卵渴,基本滿足了漢字的計(jì)算機(jī)處理需要。
但對(duì)于人名鲤竹、古漢語(yǔ)等方面出現(xiàn)的罕用字浪读、生僻字,GB2312不能處理辛藻,如部分在GB2312-1980推出以后才簡(jiǎn)化的漢字(如“啰”)碘橘、部分人名用字(如歌手陶喆的“喆”字)、臺(tái)灣及香港使用的繁體字吱肌、日語(yǔ)及朝鮮語(yǔ)漢字等痘拆,并未收錄在內(nèi)。
于是全國(guó)信息技術(shù)標(biāo)準(zhǔn)化技術(shù)委員會(huì)利用GB2312-1980未使用的碼點(diǎn)空間氮墨,收錄GB13000.1-1993的全部字符纺蛆,于1995年12月1日發(fā)布了《漢字內(nèi)碼擴(kuò)展規(guī)范(GBK)》(Guo-Biao Kuozhan國(guó)家標(biāo)準(zhǔn)擴(kuò)展碼,是根據(jù)GB13000.1-1993(GB13000下文有詳細(xì)介紹)规揪,對(duì)GB2312-1980的擴(kuò)展桥氏;英文全稱Chinese Internal Code Specification)
雖然GBK跟GB2312一樣是雙字節(jié)編碼,但GBK只要求第一個(gè)字節(jié)即高字節(jié)大于127就固定表示這是一個(gè)漢字的開(kāi)始(即GBK編碼高字節(jié)的首位必須是1猛铅;0~127當(dāng)然表示的還是ASCII字符)字支,不再像GB2312一樣要求第二個(gè)字節(jié)即低字節(jié)也必須大于127(即GBK編碼低字節(jié)首位既可以是0,也可以是1)奸忽。
正因?yàn)槿绱硕槲保鳛橥瑯邮请p字節(jié)編碼的GBK才可以收錄比GB2312更多的字符。
GBK字符集向后完全兼容GB2312月杉,同時(shí)還支持GB2312-1980不支持的部分中文簡(jiǎn)體刃跛、中文繁體、日文(不過(guò)該字符集不支持韓國(guó)文字苛萎,也是其在實(shí)際使用中與Unicode字符集相比欠缺的部分)桨昙,共收錄漢字21003個(gè)、符號(hào)883個(gè)腌歉,并提供1894個(gè)造字碼位蛙酪,簡(jiǎn)、繁體字融于一體翘盖。
GBK的編碼框架(Code Scheme):其中GBK/1收錄除GB2312字符外的其他增補(bǔ)字符桂塞,GBK/2收錄GB2312字符,GBK/3收錄CJK字符馍驯,GBK/4收錄CJK字符和增補(bǔ)字符阁危,GBK/5為非中文字符玛痊,UDC為用戶自定義字符
GB18030
中國(guó)國(guó)家質(zhì)量技術(shù)監(jiān)督局于2000年3月17日推出了GB18030-2000標(biāo)準(zhǔn),以取代GBK狂打。GB18030-2000除保留全部GBK編碼漢字之外擂煞,在第二字節(jié)再度進(jìn)行擴(kuò)展,增加了大約一百個(gè)漢字及四位元組編碼空間趴乡。
GB18030《信息交換用漢字編碼字符集基本集的補(bǔ)充》是我國(guó)繼GB2312-1980和GB13000-1993之后最重要的漢字編碼標(biāo)準(zhǔn)对省,是我國(guó)計(jì)算機(jī)系統(tǒng)必須遵循的基礎(chǔ)性標(biāo)準(zhǔn)之一。
2005年晾捏,GB18030編碼方案在GB18030-2000的基礎(chǔ)上又進(jìn)行了擴(kuò)充蒿涎,于是又有了GB18030-2005《信息技術(shù)中文編碼字符集》。
如前所述惦辛,GB18030-2000是GBK的升級(jí)版本劳秋,它的主要特點(diǎn)是在GBK基礎(chǔ)上增加了CJK中日韓統(tǒng)一表意文字?jǐn)U充A的漢字;而GB18030-2005的主要特點(diǎn)是在GB18030-2000基礎(chǔ)上又增加了CJK中日韓統(tǒng)一表意文字?jǐn)U充B的漢字裙品。
微軟也為GB18030定義了專門的代碼頁(yè):CP54936俗批,但是這個(gè)代碼頁(yè)實(shí)際上并沒(méi)有真正使用(在Windows 7的“控制面板”-“區(qū)域和語(yǔ)言”-“管理”-“非Unicode程序的語(yǔ)言”中沒(méi)有提供選項(xiàng);在Windows cmd命令行中可通過(guò)命令chcp 54936更改市怎,之后在cmd中可顯示中文岁忘,但卻不支持中文輸入)。
GB13000
在所有的GB編碼方案中区匠,除了逐步擴(kuò)展并保持向下兼容的GB2312干像、GBK、GB18030等GB系列編碼方案驰弄,還有一個(gè)與GB2312麻汰、GBK、GB18030等GB系列編碼方案不兼容的戚篙、特殊的GB編碼方案——GB13000編碼方案五鲫。(注意,雖然GBK的制定岔擂,主要目的就是為了收錄GB13000中的所有字符位喂,但GBK的編碼方式與GB13000是完全不同的。因此乱灵,習(xí)慣上所稱的GB系列編碼方案一般并不包括GB13000在內(nèi)塑崖。)
為了對(duì)世界各個(gè)國(guó)家和地區(qū)的所有字符進(jìn)行統(tǒng)一編碼,以實(shí)現(xiàn)對(duì)世界上所有字符在計(jì)算機(jī)上的統(tǒng)一處理痛倚,國(guó)際標(biāo)準(zhǔn)化組織制定了新的編碼標(biāo)準(zhǔn)——ISO/IEC 10646標(biāo)準(zhǔn)(即Universal Character Set通用字符集规婆,簡(jiǎn)稱UCS,與統(tǒng)一聯(lián)盟制定的Unicode標(biāo)準(zhǔn)兼容,兩者的關(guān)系詳見(jiàn)后文)抒蚜。
為了與國(guó)際標(biāo)準(zhǔn)接軌掘鄙,中國(guó)于是制定了與ISO/IEC 10646.1:1993標(biāo)準(zhǔn)相對(duì)應(yīng)的中國(guó)國(guó)家標(biāo)準(zhǔn)——GB13000.1-1993《信息技術(shù)通用多八位編碼字符集(UCS)第一部分:體系結(jié)構(gòu)與基本多文種平面》。
2010年又發(fā)布了其替代標(biāo)準(zhǔn)——GB13000-2010《信息技術(shù)通用多八位編碼字符集(UCS)》嗡髓,此標(biāo)準(zhǔn)等同于國(guó)際標(biāo)準(zhǔn)ISO/IEC 10646:2003《信息技術(shù)通用多八位編碼字符集(UCS)》通铲。
GB13000與國(guó)際標(biāo)準(zhǔn)ISO/IEC10646及Unicode標(biāo)準(zhǔn)目前在基本平面(即BMP,詳見(jiàn)后文)上基本保持一致器贩。各漢字(中文字符)編碼方案之間的關(guān)系(Big5為繁體漢字編碼方案,主要通行于港澳臺(tái)地區(qū)朋截,本文不作詳細(xì)介紹)
6.ANSI 編碼
ANSI原意是指美國(guó)國(guó)家標(biāo)準(zhǔn)協(xié)會(huì)蛹稍,但是在windows系統(tǒng)中,ANSI編碼意思卻代表“本地編碼”部服。 唆姐。也就是說(shuō),在中國(guó)代表GBK廓八,在臺(tái)灣代表Big5奉芦,在日本代表JIS,所以windows編程中常說(shuō)的ANSI字符串剧蹂,就是指本地編碼的字符串声功,在中國(guó),就是一種DBCS宠叼,用1個(gè)和2個(gè)字節(jié)表示一個(gè)字符的編碼先巴。
這也就是我們使用Notepad++進(jìn)行文件編寫的時(shí)候,會(huì)默認(rèn)給我們提供ANSI的編碼格式冒冬,其實(shí)就是GBK編碼啦伸蚯。
事實(shí)上并沒(méi)有ANSI編碼,ANSI是什么简烤,是American National Standards Institute美國(guó)國(guó)家標(biāo)準(zhǔn)協(xié)會(huì)剂邮,協(xié)會(huì),機(jī)構(gòu)而已横侦。ANSI也有自己的ASCII標(biāo)準(zhǔn)挥萌。但是我們看到的這個(gè)ANSI并不是特指ANSI的ASCII標(biāo)準(zhǔn),這個(gè)應(yīng)該指所有的本地化編碼丈咐。
這個(gè)是微軟的鍋瑞眼。一開(kāi)始只有英文操作系統(tǒng),用ANSI表示ANSI的Extend ASCII編碼棵逊。但是到了歐洲就是ISO-8859-1編碼伤疙,到中國(guó)應(yīng)該是GBK編碼,日本應(yīng)該是JIS編碼等等,為了把實(shí)際編碼的差異隱藏起來(lái)徒像,用所謂的ANSI編碼來(lái)表示所有Windows系統(tǒng)上的地區(qū)化編碼黍特,然后操作系統(tǒng)自己做轉(zhuǎn)換,不同的國(guó)家地區(qū)锯蛀,就會(huì)對(duì)應(yīng)不同的編碼規(guī)范灭衷。ANSI應(yīng)該叫地區(qū)化編碼,只出現(xiàn)在Windows系統(tǒng)中旁涤,就好像一種工廠模式翔曲,被Windows系統(tǒng)用來(lái)統(tǒng)一地區(qū)化編碼的叫法。
7.Unicode劈愚、UCS
以上的編碼都是本地化編碼瞳遍,一國(guó)之內(nèi)還沒(méi)有問(wèn)題,但是要跨國(guó)菌羽,就不行了掠械。比如漢字,在只有ISO-8859系列字符集的電腦上顯示就只能是亂碼了注祖,要顯示漢字猾蒂,電腦上必須裝GB2312或GBK的字符集。有沒(méi)有一個(gè)字符集是晨,能夠包含全球所有的字符呢肚菠?這就是Unicode和UCS
1988年,Joe Becker 發(fā)布了一個(gè)草案罩缴,提出了“Unicode”的概念案糙,他解釋說(shuō)“‘Unicode’是一種唯一的、統(tǒng)一的靴庆、全球的編碼”时捌。后來(lái),RLG炉抒、Sun奢讨、Microsoft、NeXT(喬布斯被趕出蘋果后創(chuàng)建的公司)的人也都逐漸加入到Unicode工作組里焰薄。1991年1月3日拿诸,Unicode聯(lián)盟組織成立,同年發(fā)布了Unicode1.0.
同時(shí)塞茅,ISO組織也在做同樣的事情亩码,創(chuàng)造一個(gè)全球統(tǒng)一的字符集(Universal Coded Character Set,簡(jiǎn)稱UCS)野瘦,1993年發(fā)布了標(biāo)準(zhǔn)ISO 10646-1描沟。
后來(lái)飒泻,兩個(gè)組織認(rèn)識(shí)到,世界不需要兩個(gè)不兼容的字符集吏廉,于是泞遗,開(kāi)始合作。從Unicode2.0開(kāi)始席覆,開(kāi)始采用和UCS相同的字庫(kù)和字碼史辙。這樣,兩個(gè)項(xiàng)目仍都存在佩伤,并獨(dú)立地公布各自的標(biāo)準(zhǔn)聊倔。但雙方都同意保持兩者標(biāo)準(zhǔn)的碼表兼容,并緊密地共同調(diào)整任何未來(lái)的擴(kuò)展生巡。所以方库,現(xiàn)在說(shuō)到UCS字符集,跟Unicode可以看成一回事障斋。
Unicode編碼包含兩個(gè)層次:第一層定義字符的數(shù)值和第二層定義數(shù)值的實(shí)現(xiàn)方式。Unicode用數(shù)字 0x0~0x10FFFF 表示所有字符徐鹤,所以最多可以容納 1114112 個(gè)字符垃环。數(shù)值的編碼方式,也就是實(shí)現(xiàn)方式包括 UTF-8返敬,UTF-16遂庄,UTF-32 三種。
有人會(huì)說(shuō)劲赠,Unicode不是兩個(gè)字節(jié)表示字符的碼涛目?為什么數(shù)值可以到0x10FFFF,這不21位凛澎,兩個(gè)半字節(jié)還多了嗎霹肝?其實(shí),這是混淆了Unicode的數(shù)值定義和實(shí)現(xiàn)塑煎,這根本就是兩個(gè)概念沫换,Unicode到底用幾個(gè)字節(jié)表示,取決于其實(shí)現(xiàn)方式是UTF-8最铁,UTF-16讯赏,還是UTF-32.
比如,“漢字”對(duì)應(yīng)的Unicode值是0x6c49和0x5b57冷尉,而編碼實(shí)現(xiàn)是:
char data_utf8[]= {0xE6,0xB1,0x89,0xE5,0xAD,0x97}; //UTF-8編碼 char16_t data_utf16[]= {0x6C49,0x5B57}; //UTF-16編碼 char32_t data_utf32[]= {0x00006C49,0x00005B57}; //UTF-32編碼
UTF-8
UTF漱挎,全稱“Unicode Transformation Formats”。是Unicode的編碼格式雀哨。
UTF-8是使用8-bit為單位磕谅,對(duì)Unicode進(jìn)行編碼的。特點(diǎn)是,對(duì)不同范圍的字符使用不同長(zhǎng)度的編碼怜庸。
Unicode編碼(十六進(jìn)制) | UTF-8 字節(jié)流(二進(jìn)制) |
---|---|
00000000 - 0000007F | 0xxxxxxx |
00000080 - 000007FF | 110xxxxx 10xxxxxx |
00000800 - 0000FFFF | 1110xxxx 10xxxxxx 10xxxxxx |
00010000 - 001FFFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
00200000 - 03FFFFFF | 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx |
04000000 - 7FFFFFFF | 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx |
UTF-8 的編碼規(guī)則很簡(jiǎn)單: 如果只有一個(gè)字節(jié)当犯,那么最高的比特位為 0;如果有多個(gè)字節(jié)割疾,那么第一個(gè)字節(jié)從最高位開(kāi)始嚎卫,連續(xù)有幾個(gè)比特位的值為 1,就使用幾個(gè)字節(jié)編碼宏榕,剩下的字節(jié)均以 10 開(kāi)頭拓诸。具體的表現(xiàn)形式為(xxx 就用來(lái)存儲(chǔ) Unicode 中的字符編號(hào)):
0xxxxxxx:?jiǎn)巫止?jié)編碼形式,這和 ASCII 編碼完全一樣麻昼,因此 UTF-8 是兼容 ASCII 的奠支;
110xxxxx 10xxxxxx:雙字節(jié)編碼形式;
1110xxxx 10xxxxxx 10xxxxxx:三字節(jié)編碼形式抚芦;
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx:四字節(jié)編碼形式倍谜。
下面是一些字符的編碼實(shí)例(綠色部分表示本來(lái)的 Unicode 編號(hào)):
字符 | N | ? | 齊 |
---|---|---|---|
Unicode 編號(hào)(二進(jìn)制) | 01001110 | 11100110 | 00101110 11101100 |
Unicode 編號(hào)(十六進(jìn)制) | 4E | E6 | 2E EC |
UTF-8 編碼(二進(jìn)制) | 01001110 | 11000011 10100110 | 11100010 10111011 10101100 |
UTF-8 編碼(十六進(jìn)制) | 4E | C3 A6 | E2 BB AC |
UTF-8編碼的最大長(zhǎng)度是6個(gè)字節(jié)。
- 對(duì)于0x00-0x7F之間的字符叉抡,UTF-8編碼與ASCII編碼完全相同,用1個(gè)字節(jié)表示尔崔,首位為0。
- 對(duì)于0x80-0x7FF之間的字符褥民,用2個(gè)字節(jié)表示季春,第一個(gè)字節(jié)前三位“110”為標(biāo)志位,第二個(gè)字節(jié)前兩位“10”為標(biāo)志位消返。剩下的11位用來(lái)表示Unicode值(7FF最多11位)载弄。
- 同樣,UTF-8的3個(gè)字節(jié)撵颊,可以表示0x800-0xFFFF的Unicode(最多16位)宇攻。
- UTF-8的4個(gè)字節(jié),可以表示0x10000-0x001FFFFF的Unicode(最多21位)倡勇。 4個(gè)字節(jié)以內(nèi)尺碰,已經(jīng)包含了Unicode所有字符。
- 5译隘、6個(gè)字節(jié)表示的已經(jīng)是非Unicode編碼范圍亲桥,屬于UCS-4 編碼。早期UTF-8規(guī)范也可以達(dá)到6字節(jié)序列固耘,不過(guò)2003年11月UTF-8 被 RFC 3629 重新規(guī)范题篷,只能使用原來(lái)Unicode定義的區(qū)域, U+0000到U+10FFFF厅目。根據(jù)規(guī)范番枚,這些字節(jié)值將無(wú)法出現(xiàn)在合法 UTF-8序列中法严。
例1:“漢”字的Unicode編碼是0x6C49。0x6C49在0x0800-0xFFFF之間葫笼,使用用3字節(jié)模板了:1110xxxx 10xxxxxx 10xxxxxx深啤。將0x6C49寫成二進(jìn)制是:0110 1100 0100 1001, 用這個(gè)比特流依次代替模板中的x路星,得到:11100110 10110001 10001001溯街,即E6 B1 89。
例2:Unicode編碼0x20C30在0x010000-0x10FFFF之間洋丐,使用用4字節(jié)模板了:11110xxx 10xxxxxx 10xxxxxx 10xxxxxx呈昔。將0x20C30寫成21位二進(jìn)制數(shù)字(不足21位就在前面補(bǔ)0):0 0010 0000 1100 0011 0000,用這個(gè)比特流依次代替模板中的x友绝,得到:11110000 10100000 10110000 10110000橄唬,即F0 A0 B0 B0疾棵。
UTF-8有兩個(gè)好處:
- 1字節(jié)字符、2字節(jié)字符料皇、3字節(jié)字符……的首字節(jié)標(biāo)志位不同咬腕,這樣可以很清楚的區(qū)分一個(gè)字節(jié)屬于1字節(jié)字符還是2字節(jié)字符咏删,如果一個(gè)字節(jié)流傳輸中出現(xiàn)錯(cuò)誤秦士,也不會(huì)錯(cuò)位舷夺,只影響部分字符,根據(jù)標(biāo)志位切威,很容易找到下個(gè)正確字符。
- 兼容ASCII碼丙号, 英美字符用UTF-8可以一個(gè)字節(jié)表示先朦,所以,www組織選用UTF-8作為推薦編碼格式犬缨。2007年喳魏,在互聯(lián)網(wǎng)上,UTF-8格式已經(jīng)超過(guò)了ASCII碼怀薛。
UTF-16
UTF-16以2字節(jié)為單位,等同于UCS-2.
Unicode編碼(十六進(jìn)制) | UTF-16 字節(jié)流(二進(jìn)制) |
---|---|
00000000 - 0000FFFF | xxxxxxxx xxxxxxxx |
00010000 - 0010FFFF | 110110yyyyyyyyyy 110111xxxxxxxxxx |
Unicode值小于等于0xFFFF的刺彩,直接用兩個(gè)字節(jié)表示,超過(guò)0xFFFF的枝恋,無(wú)法用兩個(gè)字節(jié)表示创倔。使用下面公式編碼:
-
1.計(jì)算 U’= U – 0x10000 2. 將U'寫成二進(jìn)制形式:yyyy yyyy yyxx xxxx xxxx 3. 加上標(biāo)志位,1101 10yy yyyy yyyy 1101 11xx xxxx xxxx:高位代理值為D800焚碌,低位代理值為DC00
可見(jiàn)畦攘,這是4個(gè)字節(jié)表示,2個(gè)6位標(biāo)志位十电,20位有效位知押。因?yàn)閁最大是0x10FFFF叹螟,所以U’最大是0xFFFFF,20位足夠表示台盯。
案例1:
U+0020罢绽,這個(gè)值的范圍在第一部分,即經(jīng)過(guò)UTF-16編碼后静盅,結(jié)果仍然為U+0020良价,在內(nèi)存中的順序?yàn)?0 20。
案例2:
U+12345, 這個(gè)值的范圍在第二部分温亲,因此需要先減去0x10000棚壁,得到0x02345,拆分成高10位00 0000 1000和低10位11 0100 0101栈虚。根據(jù)上面規(guī)則加上特定值后袖外,高位代理值為D808,低位代理值為DF45魂务,最終內(nèi)存中的順序?yàn)镈8 08 DF 45曼验。
BOM的含義
BOM即Byte Order Mark字節(jié)序標(biāo)記。BOM是為UTF-16和UTF-32準(zhǔn)備的粘姜,用戶標(biāo)記字節(jié)序(byte order)鬓照。拿UTF-16來(lái)舉例,其是以兩個(gè)字節(jié)為編碼單元孤紧,在解釋一個(gè)UTF-16文本前豺裆,首先要弄清楚每個(gè)編碼單元的字節(jié)序。例如收到一個(gè)“奎”的Unicode編碼是594E号显,“乙”的Unicode編碼是4E59臭猜。如果我們收到UTF-16字節(jié)流"594E",那么這是“奎”還是“乙”押蚤?
我們先來(lái)來(lái)看下UTF-16-Big Endian文件格式:
可以看到此時(shí)“文件”二字的unicode編碼并沒(méi)有超過(guò)0xFFFF蔑歌,所以使用兩個(gè)字節(jié)來(lái)保存:
而最早的“fe ff”即為Bom標(biāo)簽。
我們?cè)賮?lái)看下UTF-16-Little Endian文件格式:
使用的Bom標(biāo)簽居然變?yōu)榱薴ffe揽碘。
Unicode規(guī)范中推薦的標(biāo)記字節(jié)順序的方法是BOM:在UCS編碼中有一個(gè)叫做"ZERO WIDTH NO-BREAK SPACE"(零寬度無(wú)間斷空間)的字符次屠,它的編碼是FEFF。而FEFF在UCS中是不不能再的字符(即不可見(jiàn))雳刺,所以不應(yīng)該出現(xiàn)在實(shí)際傳輸中劫灶。UCS規(guī)范建議我們?cè)趥鬏斪止?jié)流前,先傳輸字符"ZERO WIDTH NO-BREAK SPACE"掖桦。這樣如果接收者接收到FEFF浑此,就表明這個(gè)字節(jié)流是Big-Endian的;如果收到FFFE滞详,就表明這個(gè)字節(jié)流是Little-Endian的凛俱。因此字符"ZERO WIDTH NO-BREAK SPACE"又被稱為BOM紊馏。
windows上默認(rèn)的Unicode編碼方式就是UTF-16,使用wchar_t表示蒲犬。
UTF-32
UTF-32編碼以4字節(jié)為單位朱监。直接把Unicode值轉(zhuǎn)為4字節(jié)二進(jìn)制數(shù)就是其UTF-32編碼。等同于UCS-4.
8.Base64
有的電子郵件系統(tǒng)(比如國(guó)外信箱)不支持非英文字母(比如漢字)傳輸原叮,這是歷史原因造成的(認(rèn)為只有美國(guó)會(huì)使用電子郵件?)赫编。因?yàn)橐粋€(gè)英文字母使用ASCII編碼來(lái)存儲(chǔ),占存儲(chǔ)器的1個(gè)字節(jié)(8位)奋隶,實(shí)際上只用了7位2進(jìn)制來(lái)存儲(chǔ)擂送,第一位并沒(méi)有使用,設(shè)置為0唯欣,所以嘹吨,這樣的系統(tǒng)認(rèn)為凡是第一位是1的字節(jié)都是錯(cuò)誤的。而有的編碼方案(比如GB2312)不但使用多個(gè)字節(jié)編碼一個(gè)字符境氢,并且第一位經(jīng)常是1蟀拷,于是郵件系統(tǒng)就把1換成0,這樣收到郵件的人就會(huì)發(fā)現(xiàn)郵件亂碼萍聊。
為了能讓郵件系統(tǒng)正常的收發(fā)信件问芬,就需要把由其他編碼存儲(chǔ)的符號(hào)轉(zhuǎn)換成ASCII碼來(lái)傳輸。比如寿桨,在一端發(fā)送GB2312編碼->根據(jù)Base64規(guī)則->轉(zhuǎn)換成ASCII碼此衅,接收端收到ASCII碼->根據(jù)Base64規(guī)則->還原到GB2312編碼。
9.Big5
在臺(tái)灣亭螟、香港與澳門地區(qū)挡鞍,使用的是繁體中文字符集。而1980年發(fā)布的GB2312面向簡(jiǎn)體中文字符集媒佣,并不支持繁體漢字匕累。在這些使用繁體中文字符集的地區(qū)陵刹,一度出現(xiàn)過(guò)很多不同廠商提出的字符集編碼默伍,這些編碼彼此互不兼容,造成了信息交流的困難衰琐。為統(tǒng)一繁體字符集編碼也糊,1984年,臺(tái)灣五大廠商宏碁羡宙、神通狸剃、佳佳、零壹以及大眾一同制定了一種繁體中文編碼方案狗热,因其來(lái)源被稱為五大碼钞馁,英文寫作Big5虑省,后來(lái)按英文翻譯回漢字后,普遍被稱為大五碼僧凰。 大五碼是一種繁體中文漢字字符集探颈,其中繁體漢字13053個(gè),808個(gè)標(biāo)點(diǎn)符號(hào)训措、希臘字母及特殊符號(hào)伪节。大五碼的編碼碼表直接針對(duì)存儲(chǔ)而設(shè)計(jì),每個(gè)字符統(tǒng)一使用兩個(gè)字節(jié)存儲(chǔ)表示绩鸣。第1字節(jié)范圍81H-FEH怀大,避開(kāi)了同ASCII碼的沖突,第2字節(jié)范圍是40H-7EH和A1H-FEH呀闻。因?yàn)锽ig5的字符編碼范圍同GB2312字符的存儲(chǔ)碼范圍存在沖突化借,所以在同一正文不能對(duì)兩種字符集的字符同時(shí)支持。 Big5編碼的分布如表1-5所示总珠,Big5字符主要部分集中在三個(gè)段內(nèi):標(biāo)點(diǎn)符號(hào)屏鳍、希臘字母及特殊符號(hào);常用漢字局服;非常用漢字钓瞭。其余部分保留給其他廠商支持。
Big5編碼推出后淫奔,得到了繁體中文軟件廠商的廣泛支持山涡,在使用繁體漢字的地區(qū)迅速普及使用。目前唆迁,Big5編碼在臺(tái)灣鸭丛、香港、澳門及其他海外華人中普遍使用唐责,成為了繁體中文編碼的事實(shí)標(biāo)準(zhǔn)鳞溉。在互聯(lián)網(wǎng)中檢索繁體中文網(wǎng)站,所打開(kāi)的網(wǎng)頁(yè)中鼠哥,大多都是通過(guò)Big5編碼產(chǎn)生的文檔熟菲。
總結(jié)各種字符編碼之間的關(guān)系
上面關(guān)于字符集和編碼講了許多概念,其實(shí)歸類一下可以這么理解: 首先是單字節(jié)字符集:
- 1朴恳、最初美國(guó)ANSI發(fā)明了自己的編碼ASCII抄罕,7-bit足夠,這是標(biāo)準(zhǔn)ASCII于颖。
- 2呆贿、標(biāo)準(zhǔn)ASCII碼沒(méi)有西歐國(guó)家拉丁文、英鎊等字符森渐,各公司做入、國(guó)家開(kāi)始擴(kuò)展冒晰,形成自己的擴(kuò)展ASCII碼字符集,各方混戰(zhàn)竟块,不過(guò)8-bit也就足夠翩剪。
- 3、天下分久必合彩郊,ISO統(tǒng)一了8-bit字符集前弯,叫做ISO 8859.
但是亞洲國(guó)家字符更多,一個(gè)字節(jié)遠(yuǎn)遠(yuǎn)不夠秫逝,于是用多個(gè)字節(jié)表示恕出,擴(kuò)展形成本國(guó)字符集,中國(guó)GB系列违帆,臺(tái)灣Big5浙巫,日本JIS……,這些叫做多字節(jié)字符集(MBCS)刷后,windows中用雙字節(jié)表示的畴,也叫做(DBCS)。
以上字符都是群雄割據(jù)尝胆,各自為政丧裁,windows為了迎合大家需求,在哪個(gè)國(guó)家含衔,默認(rèn)編碼就用那個(gè)國(guó)家的煎娇,不過(guò)后來(lái)不知怎么被誤傳位ANSI編碼,其實(shí)ANSI怎么可能定義世界各國(guó)編碼贪染,不過(guò)可以理解成各編碼都是在ANSI*礎(chǔ)上擴(kuò)展的缓呛,因?yàn)槎技嫒軦NSI的標(biāo)準(zhǔn)ASCII碼。
這時(shí)杭隙,ISO再次出手哟绊,和Unicode聯(lián)盟攜手打造了Unicode(UCS),意圖一統(tǒng)江湖痰憎。Unicode確實(shí)包羅萬(wàn)象票髓,涵蓋了各國(guó)字符,于是流行世界信殊。Unicode自身只定義了每個(gè)字符的數(shù)值炬称,真正二進(jìn)制編碼格式卻是UTF-8汁果,UTF-16(UCS-2)涡拘,UTF-32(UCS-4)。
至此据德,天下一統(tǒng)鳄乏,但愿程序員的太平盛世到來(lái)了跷车!我是小余,我們下期見(jiàn)橱野。
參考
刨根究底字符編碼之五——簡(jiǎn)體漢字編碼方案(GB2312朽缴、GBK等)以及全角、半角水援、CJK
https://en.wikibooks.org/wiki/Unicode/Character_reference/D000-DFFF