字符集、編碼的前世今生
當(dāng)前位置:點(diǎn)晴教程→知識管理交流
→『 技術(shù)文檔交流 』
1 ASCII的誕生20世紀(jì)60年代的美國,計(jì)算機(jī)發(fā)展到集成電路階段,體積不斷縮小,功能不斷增強(qiáng),應(yīng)用軟件開始出現(xiàn)。但當(dāng)時(shí)每個(gè)廠家都按自己的喜好來編碼,有的用6位表示一個(gè)字符,有的用7位表示一個(gè)字符,不同廠家之間有不同標(biāo)準(zhǔn),軟件不能跨設(shè)備運(yùn)行,兩個(gè)廠家生產(chǎn)出來的計(jì)算機(jī)無法交流。當(dāng)時(shí),編碼方式超過60種,僅IBM一家公司在自家不同的設(shè)備上就有9種不同的編碼。這時(shí)IBM里有位程序員意識到了這個(gè)問題,他認(rèn)為所有廠家的編碼應(yīng)該統(tǒng)一起來,并且從1960年開始干這個(gè)活,一年后他向ANSI(美國國家標(biāo)準(zhǔn)協(xié)會)提出統(tǒng)一計(jì)算機(jī)編碼的建議,ANSI覺得這個(gè)想法不錯(cuò),于是把各大廠商召集起來開會,利益紛爭的座談會一直開到1967年,ANSI實(shí)在受不了了,說算了你們別爭了,26個(gè)英文字母加10個(gè)數(shù)字加常用的書寫符號再加流行的打印控制湊齊128個(gè),用7位存儲,前面32個(gè)用于控制,后面的用于顯示,128一二發(fā),大吉大利,就這樣定了吧。 次年,美國總統(tǒng)林登·約翰遜下達(dá)紅頭文件,所有的計(jì)算機(jī)廠家必須遵循ANSI的標(biāo)準(zhǔn)。于是,大名鼎鼎的ASCII誕生。促成ASCII編碼的這位IBM員工的名字是:Bob Bemer(鮑勃·貝莫) 2 ASCII的自由擴(kuò)展以后的若干年,ASCII在美國不溫不火,各廠家拿著紅頭文件照章辦事,直到1981年,一件石破天驚的事情讓世人重新重視和開始討論ASCII,這就是IBM個(gè)人電腦(PC)的誕生。PC完全顛覆了人們對計(jì)算機(jī)的印象,它成本低廉,體積小巧,很快就開始在全球蔓延。PC到了英國,英國人發(fā)現(xiàn)他們的英鎊符號£在萬能的PC里顯示不出來;PC到了希臘,希臘人發(fā)現(xiàn)讓他們引以為傲的希臘字母居然在PC里一個(gè)也敲不進(jìn)去。IBM根據(jù)市場反饋,很快就決定把ANSI的7位ASCII標(biāo)準(zhǔn)擴(kuò)展成8位,這樣就多出了一倍的字符。 當(dāng)時(shí)生產(chǎn)PC的可不止IBM一家,大多數(shù)人知道現(xiàn)在的iPhone、iPad稱霸全球,但很多人不知道早在1977年喬幫主的Apple II就在江湖上叱詫風(fēng)云。同樣,喬幫主也毫不猶豫的把ANSI的7位擴(kuò)展成了8位,還特意把240這個(gè)值設(shè)計(jì)成蘋果的標(biāo)識。俗話說性格決定命運(yùn),也許喬幫主在擴(kuò)展ASCII中畫下被啃掉一口蘋果的那天,就決定了30年后創(chuàng)造出的萬億美元市值公司。 3 GB2312信息革命是繼蒸汽革命、電氣革命之后人類歷史上第三次科技革命,雖然信息革命發(fā)源于美國,但中國人民很早就意識到了信息革命的重要性。在IBM電腦興起的時(shí)候,我們召開完了十一界三中全會,聰明勤勞的中國人民敏銳的意識到漢字也需要信息化,但美帝規(guī)定的ASCII只有7位,即便擴(kuò)展為8位,也容納不下博大精深的漢字,于是我們毫不猶豫的把一個(gè)字節(jié)擴(kuò)展成兩個(gè)字節(jié),考慮到兼容ASCII,將前面32個(gè)控制字符排除掉,高低位字節(jié)組合起來就有94X94=8836個(gè),掐指一算,常用漢字夠了,順帶還可以將ASCII用兩個(gè)字節(jié)再重編碼一遍,于是便有了今天的全角半角字符之分。 1980年,中國國家標(biāo)準(zhǔn)總局制定了《信息交換用漢字編碼字符集》,1981年5月1日開始正式實(shí)施,標(biāo)準(zhǔn)號是:GB2312-80,選入了6763個(gè)漢字,分為兩級,一級字庫中有3755個(gè),是常用漢字,二級字庫中有3008個(gè),是次常用漢字;還選入了682個(gè)非漢字圖型字符,包含數(shù)字、一般符號、拉丁字母、日本假名、希臘字母、俄文字母、拼音符號、注音字母等。整個(gè)字符集分成94個(gè)區(qū),每區(qū)有94個(gè)位。每個(gè)區(qū)位上只有一個(gè)字符,因此可用所在的區(qū)和位來對漢字進(jìn)行編碼,稱為區(qū)位碼。1996年我們學(xué)校機(jī)房所有的486電腦上統(tǒng)一安裝的就是拼音、五筆和從來沒人會用的區(qū)位碼。 4 BIG5因?yàn)樘厥鈿v史背景原因,GB2312在設(shè)計(jì)時(shí)并未考慮支持繁體中文,當(dāng)時(shí)作為亞洲四小龍之一的臺灣省,經(jīng)濟(jì)騰飛,計(jì)算機(jī)快速普及,但同樣,臺灣廠商各自采用不同的中文編碼方式,數(shù)據(jù)交互困難,臺灣人民的屏幕上亂碼滿天飛。于是在1983-1984年間,宏基(Acer)、神通(Mitac)、佳佳(KaoHSIN)、零一(Zero One)、大眾(FIC)五家商業(yè)公司共同制定了統(tǒng)一的繁體中文編碼標(biāo)準(zhǔn),也許他們覺得自己應(yīng)該是臺灣最大的五家公司,所以將這個(gè)編碼稱之為大五碼(BIG5)。BIG5采用雙字節(jié)編碼,收錄了常用與次常用繁體漢字13060個(gè),以及日、俄、希臘字母、標(biāo)點(diǎn)符號等共計(jì)1.9萬個(gè)字符,但遺憾的是BIG5不支持簡體中文,也不兼容GB2312,這樣在一個(gè)國家的兩個(gè)地區(qū),使用著相同的語言文字,但計(jì)算機(jī)中存儲著兩種完全不同的編碼。 5 GBK時(shí)間來到九十年代,中國的改革開放在小平同志的帶領(lǐng)下初見成效,兩岸三地的經(jīng)濟(jì)文化交流日益頻繁,普通家庭開始擁有個(gè)人電腦。同時(shí),遠(yuǎn)在大洋彼岸的比爾蓋茨正帶領(lǐng)著微軟緊鑼密鼓的開發(fā)著劃時(shí)代的操作系統(tǒng)Windows95,他們發(fā)現(xiàn)GB2312標(biāo)準(zhǔn)并不支持一些實(shí)際使用的漢字,比如常用于人名的“镕”、“喆”、“犇”、“垚”等,于是微軟開始在GB2312的基礎(chǔ)上進(jìn)行擴(kuò)展,除了增加GB2312標(biāo)準(zhǔn)中不支持的簡體字,還打包了BIG5中所有繁體字以及日韓語中使用的漢字共計(jì)21003個(gè),將其命名為“國標(biāo)擴(kuò)展(Guo Biao Kuozhan)”,縮寫就是“GBK”。因?yàn)镚BK并不是國家標(biāo)準(zhǔn),只是微軟作為商業(yè)公司基于市場需求推出的編碼規(guī)范,所以這也為后來中文編碼的標(biāo)準(zhǔn)化埋下了隱患。 微軟作為一家美國公司,之所以能果斷快速的基于GB2312擴(kuò)展出GBK,完全是借助了另一支強(qiáng)大力量,1993年,國際標(biāo)準(zhǔn)化組織(ISO)和國際電工委員會(IEC)聯(lián)合發(fā)布了ISO/IEC 10646-1,這是旨在統(tǒng)一全球編碼的一份國際標(biāo)準(zhǔn),從西方的拉丁語、希臘語、斯拉夫語,到東方的日語、韓語、漢語,包括GB2312與BIG5中的字符,均在涵蓋范圍之內(nèi)。同年,中國國家技術(shù)監(jiān)督局采用了ISO/IEC 10646-1,頒布國標(biāo)GB13000.1。所以微軟只是將GB2312與ISO/IEC 10646-1兩大標(biāo)準(zhǔn)進(jìn)行了融合,它充當(dāng)了國家標(biāo)準(zhǔn)向國際標(biāo)準(zhǔn)磨合過渡的潤滑劑,滿足那段特殊歷史時(shí)期的市場需求,GBK編碼也隨著Windows95迅速走進(jìn)了中國的千家萬戶。 再來看一下使用粵語的香港和澳門地區(qū),他們與臺灣一樣使用的是繁體字,所以字符編碼采用BIG5,但粵語中的一些特殊字符比如“邨”、“埗”、“涌”,在BIG5并未支持,于是香港政府不得不發(fā)布香港增補(bǔ)字符集(HKSCS,Hong Kong Supplementary Character Set)。 我們回顧一下當(dāng)時(shí)的中文編碼情況,支持簡體中文的GB2312,支持繁體中文的BIG5,基于BIG5為粵語打的補(bǔ)丁HKSCS,計(jì)劃但尚未完成一統(tǒng)天下的ISO/IEC 10646,支持GB2312與BIG5中的字符但兩者編碼又不兼容的國標(biāo)GB13000.1,兼容GB2312且支持BIG5中字符但不是國標(biāo)的GBK,真是一個(gè)萬碼奔騰的時(shí)代! 6 Unicode的誕生在漫長的人類發(fā)展歷史中,有些人總能看穿時(shí)間,洞悉未來。比如來自蘋果和施樂公司的工程師Mark Davis、Lee Collins和Joe Becker,早在1987年就認(rèn)為全世界所有文字符號終將融合,需要一份統(tǒng)一的編碼,他們于1988年發(fā)布了第一個(gè)試行標(biāo)準(zhǔn)Unicode 88,又于1991年推出了正式標(biāo)準(zhǔn)Unicode 1.0并成立Unicode聯(lián)盟。與Unicode有著相同偉大構(gòu)想的還有另外兩家美國事業(yè)單位,也是上一章中曾經(jīng)提到過的國際標(biāo)準(zhǔn)化組織(ISO)和國際電工委員會(IEC),他們計(jì)劃通過通用字符集(UCS,Universal Character Set)統(tǒng)一全世界的字符編碼并為此進(jìn)行了多年的工作。幸運(yùn)的是Unicode與ISO/IEC兩個(gè)項(xiàng)目組都意識到這個(gè)世界不需要兩種不兼容的字符集,自從他們知道了彼此的存在后便約定將協(xié)同工作,編碼完全相互兼容,并且以Unicode的名號昭告天下,因?yàn)檫@個(gè)名字更容易被記住。稍有遺憾的是說英語的美國人嚴(yán)重低估了這個(gè)世界其它語言的復(fù)雜性,早期的Unicode團(tuán)隊(duì)認(rèn)為16位支持的65536個(gè)字符足夠這個(gè)世界使用,但其實(shí)這個(gè)長度還不夠存放中國的象形文字,這些都不影響Unicode的偉大,只是在漫長的90年代,Unicode不溫不火,隱姓埋名,它在等待逆天改命的一個(gè)機(jī)會。 1999年,一款名為OICQ的即時(shí)通訊軟件火遍了中國大江南北,那年我上大一,成宿的跟異性網(wǎng)友在OICQ上聊天,現(xiàn)在的年青人無法理解,是因?yàn)樗麄儫o法體會從郵寄信件的筆友突然跨越到OICQ聊天的那種代差感;同時(shí),新浪、網(wǎng)易、搜狐三大門戶已將傳統(tǒng)紙媒打折了腿下一步就該按在地上摩擦了;初代網(wǎng)絡(luò)游戲《石器時(shí)代》已開始改變玩家們對游戲的認(rèn)知,而幫助陳天橋成為中國首富的《傳奇》也正在韓國發(fā)布上線?;ヂ?lián)網(wǎng)的驚濤駭浪正在席卷全球,所有國家的人們,都迫切的需要一個(gè)統(tǒng)一的字符集編碼,而Unicode,正是那個(gè)不二之選。從1991到1998的七年間,Unicode只迭代了4個(gè)版本,而從1998到1999的一年時(shí)間,Unicode就迭代了5個(gè)版本。 7 Unicode的規(guī)則很多人誤以為Unicode與GB2312、GBK、甚至UTF-8一樣,是一種具體的字符集編碼方式。其實(shí)Unicode并不是某種字符集編碼,而是一個(gè)標(biāo)準(zhǔn)化組織,負(fù)責(zé)制定一系列規(guī)則,基于這些規(guī)則,Unicode推出了三種具體的編碼:UTF-8、UTF-16、UTF-32。 規(guī)則1:Unicode字符編碼空間為U+0000至U+10FFFF碼點(diǎn)是為每個(gè)字符分配的唯一數(shù)字標(biāo)識,在Unicode中以U+作為前綴,以16進(jìn)制表示,比如字母“A”的Unicode碼點(diǎn)是U+0041(十進(jìn)制為65),漢字“中”的碼點(diǎn)是U+4E2D(十進(jìn)制為20013),碼點(diǎn)的取值范圍叫做編碼空間。 細(xì)心的你也許留意到了,Unicode編碼空間的起始U+0000與結(jié)束U+10FFFF,長度并不一樣。是的,大多數(shù)事物并非天生完美而是靠后天不斷完善的,Unicode最早計(jì)劃使用兩個(gè)字節(jié)16位支持65536個(gè)碼點(diǎn),但遇到中國的象形文字后發(fā)現(xiàn)這個(gè)范圍明顯太小了,而好基友ISO計(jì)劃使用四個(gè)字節(jié)32位支持大約4億個(gè)碼點(diǎn),又明顯太大了,于是雙方一合計(jì),掐頭去尾21位支持一百多萬碼點(diǎn),差不多剛剛好,于是編碼空間的上限便從U+FFFF(216)擴(kuò)展到了U+10FFFF(221)。 Unicode編碼空間被均分為17份,稱為17個(gè)平面(Plane),編號0到16,每個(gè)平面包含為216即65536個(gè)碼點(diǎn),平面又進(jìn)一步劃分為塊(Block),不同平面不同塊中存儲著不同類型的Unicode字符集。 規(guī)則2:具有相同含義的字符是同一個(gè)字符Unicode規(guī)定了字符抽象原則,一個(gè)字符可能有多種形狀,但只要它們具有相同的含義,就認(rèn)為是同一個(gè)字符,比如同一個(gè)漢字,行、楷、隸、草不同字體下的形狀各不相同,但Unicode認(rèn)為它們是同一個(gè)漢字,分配唯一的碼點(diǎn)。 規(guī)則3:使用簡單字符組合出復(fù)雜字符Unicode還規(guī)定了動態(tài)組合原則,使用簡單的字符組合出復(fù)雜的字符,比如瑞典語字符?,就是由字母A和 ? 組合而成。 規(guī)則4:兼容以前的字符集編碼Unicode誕生于萬碼崩騰的年代,目標(biāo)是統(tǒng)一市面上所有的字符集編碼,為了這個(gè)目標(biāo),Unicode聯(lián)盟在成立之初便制定了一項(xiàng)重要原則:雙向兼容所有現(xiàn)有字符集的編碼標(biāo)準(zhǔn)。所謂雙向兼容,就是當(dāng)前任何字符集中的任何一個(gè)編碼都可以轉(zhuǎn)換為Unicode,并且可以再從Unicode轉(zhuǎn)換回原有字符集。因此,在Unicode中就存在一些“冗余”字符,比如拉丁字母“K”與熱力學(xué)單位“K”(開爾文)看起來完全一樣,但為了與之前一些字符集編碼的兼容,它們在Unicode中存在兩個(gè)不同的碼點(diǎn),U+004B為拉丁字母K,名稱為“Latin Capital Letter K”,U+212A為熱力學(xué)單位K,名稱為“KELVIN SIGN”。Unicode中的每個(gè)碼點(diǎn)都有一個(gè)全局唯一的大寫名稱,https://www.unicode.org/Public/UNIDATA/NamesList.txt可以查看所有Unicode字符名稱。 8 UTF-8一統(tǒng)江湖Unicode聯(lián)盟根據(jù)自己制定的一系列規(guī)則,推出了三種具體的編碼方案:UTF-8、UTF-16、UTF-32。其中數(shù)字8、16、32稱之為碼元,表示在計(jì)算機(jī)中存儲Unicode字符的最小單元,比如UTF-8的碼元為8位,如果8位存不下一個(gè)字符就會擴(kuò)展至8的整倍數(shù)16位,16位再存不下就會擴(kuò)展至24位,而不允許使用9位或10位。UTF的含義是Unicode轉(zhuǎn)換格式(Unicode Translation Format),它負(fù)責(zé)將Unicode碼點(diǎn)以特定的碼元存儲在計(jì)算機(jī)中,所以UTF-8表示使用8位碼元存儲數(shù)據(jù),UTF-16表示使用16位碼元存儲數(shù)據(jù),UTF-32表示使用32位碼元存儲數(shù)據(jù)。 Unicode最早推出的是16位雙字節(jié)的定長編碼方案,但這個(gè)方案有一個(gè)致命缺陷,就是不兼容ASCII,我們知道ASCII是在1968年誕生的,而Unicode的推出時(shí)間已到了九十年代,這前后二十多年間,世界上產(chǎn)生了大量基于ASCII的文檔和軟件,要讓它們?nèi)繌?位ASCII遷移至16位Unicode,幾乎不可能。Unicode很快意識到這個(gè)問題,并馬上推出了兼容ASCII的方案:UTF-8,UTF-8也是目前使用最廣泛的編碼。 UTF-8是一個(gè)變長編碼方案,允許使用1-4個(gè)字節(jié)來存放一個(gè)Unicode字符,編碼邏輯如下: 首先判斷第一個(gè)字節(jié)的最高位,如果為0,表示這是一個(gè)單字節(jié)ASCII字符(此處不得不佩服ASCII編碼當(dāng)初保留了最高位這個(gè)神英明神武的決定,否則后續(xù)的所有多字節(jié)編碼方案都難以兼容ASCII了)。 如果最高位為1,表示這是一個(gè)多字節(jié)Unicode字符,從第1位開始連續(xù)有n個(gè)1(遇0結(jié)束)代表著這個(gè)字符連續(xù)占用了n個(gè)字節(jié),然后后續(xù)的這n個(gè)字節(jié)中,前兩位固定為標(biāo)識符,后6位存放數(shù)據(jù)。
為便于理解,如上表格展示了UTF-8編碼中1個(gè)字節(jié)到4個(gè)字節(jié)字符的編碼示例,其中x表示數(shù)據(jù)位。因?yàn)閁TF-8是目前使用最廣泛的編碼,基于兼容性考慮,在可預(yù)計(jì)的將來UTF-8也將具有長期統(tǒng)治地位,所以對于UTF-16與UTF-32本文就不作展開了。 轉(zhuǎn)自https://www.cnblogs.com/wubayue/p/18907899 該文章在 2025/6/5 15:36:40 編輯過 |
關(guān)鍵字查詢
相關(guān)文章
正在查詢... |