【字符編碼】你真的了解字符編碼嗎

騰訊大講堂——字符編碼的前世今生
字符串岛抄,那些你不知道的事
編碼字符集標(biāo)準(zhǔn)及分類研究
通信用語(yǔ)の基礎(chǔ)知識(shí) —— ISO/IEC 2022
ISO 2022 介紹(1): 標(biāo)準(zhǔn)

1. 說(shuō)明

1.1 字符編碼貢獻(xiàn)的相關(guān)的組織

  • ANSI:美國(guó)國(guó)家標(biāo)準(zhǔn)學(xué)會(huì),發(fā)布了ASCII編碼。是ISO/IEC中的一員录肯,曾和ECMA聯(lián)合制定過(guò)ECMA-94驴一。

  • ECMA:ECMA是歐洲標(biāo)準(zhǔn)組織梳虽,當(dāng)時(shí)ASCII只適合英國(guó)美國(guó)使用楼入,因?yàn)樗麄兊睦∽帜笡](méi)有變音字母,所以128個(gè)字符夠用要销。但是歐洲許多國(guó)家并不夠用构回,所以ECMA制定了一些相關(guān)標(biāo)準(zhǔn)。

  • ISO/IEC:分別是國(guó)際標(biāo)準(zhǔn)化組織International Organization for Standardization和國(guó)際電工委員會(huì)International Electrotechnical Commission疏咐。國(guó)際化標(biāo)準(zhǔn)組織也意識(shí)到統(tǒng)一字符編碼是他們的工作纤掸,所以聯(lián)合IEC開(kāi)始制定標(biāo)準(zhǔn),并且將一些現(xiàn)有的標(biāo)準(zhǔn)納入國(guó)際標(biāo)準(zhǔn)浑塞,例如ASCII對(duì)應(yīng)ISO/IEC 646借跪, ECMA-35對(duì)應(yīng)ISO/IEC 2022。ECMA-94對(duì)應(yīng)ISO/IEC 8859-1 ~ ISO/IEC 8859-4缩举。

  • 統(tǒng)一碼聯(lián)盟:The Unicode Consortium,是一個(gè)統(tǒng)籌統(tǒng)一碼(Unicode)發(fā)展的非營(yíng)利機(jī)構(gòu),其宗旨為最終以統(tǒng)一碼取代現(xiàn)存的字符編碼仅孩,因?yàn)楝F(xiàn)存編碼不能夠在多語(yǔ)言電腦環(huán)境中使用托猩,而且字符數(shù)有局限。同時(shí)它也制定了數(shù)種統(tǒng)一碼轉(zhuǎn)換格式(UTF辽慕,Unicode Transformation Format)京腥。統(tǒng)一碼的成功讓電腦使用進(jìn)入了一個(gè)新紀(jì)元,并應(yīng)用于很多新技術(shù)溅蛉,如XML公浪、Java編程語(yǔ)言和現(xiàn)今的操作系統(tǒng)。

1.2 相關(guān)術(shù)語(yǔ)說(shuō)明

由于歷史遺留問(wèn)題船侧,字符集欠气、字符編碼、編碼表這三個(gè)術(shù)語(yǔ)不用區(qū)分的太清楚镜撩,一般都是在說(shuō)同一個(gè)東西预柒。
而碼位就很明確了,就是說(shuō)字符集中有多少個(gè)碼位袁梗,例如ASCII有128個(gè)碼位宜鸯,而每個(gè)碼位又對(duì)應(yīng)一個(gè)編碼(或者說(shuō)編號(hào)也行),例如a的碼位是97遮怜,a的編碼是97淋袖。

重點(diǎn)說(shuō)下字符編碼,編碼的意思并不是說(shuō)編成計(jì)算機(jī)中的二進(jìn)制锯梁,而是賦予字符一個(gè)碼位即碗,還是例如a是97……
而97在計(jì)算機(jī)中,使用7位涝桅,還是一個(gè)字節(jié)拜姿,還是兩個(gè)字節(jié)就不知道了。
不過(guò)要說(shuō)編碼的意思就是編程二進(jìn)制也不完全錯(cuò)冯遂,所以這幾個(gè)屬于概念的界限是很模糊的蕊肥。如

  • 等同于:文章中可能出現(xiàn)等同于這個(gè)說(shuō)法,例如GB13000等同于Unicode1.1蛤肌,指的是等同采用壁却,另外還有修改采用,和非等效采用這里就不多說(shuō)了裸准≌苟可以看百度百科——國(guó)家標(biāo)準(zhǔn)代碼

2. 字符編碼的發(fā)展

下面基本是按照發(fā)展順序排列,但并不全是炒俱。想知道大概發(fā)展時(shí)間的可以看 騰訊大講堂——字符編碼的前世今生

2.1 ASCII

American Standard Code for Information Interchange 美國(guó)信息轉(zhuǎn)換標(biāo)準(zhǔn)代碼

ASCII第一次以規(guī)范標(biāo)準(zhǔn)的類型發(fā)表是在1967年(最早公布于19)盐肃。它是一種7bit字符集爪膊,一共能表示128種符號(hào)。
而ASCII編碼設(shè)計(jì)于早期砸王,它的作用不僅只是顯示字符推盛,還包含一些控制字符,用于文本控制谦铃,操作終端等耘成,例如7(0000 01110x07)是代表響鈴驹闰,10代表?yè)Q行鍵瘪菌。
控制字符一共有33個(gè),分別是0~31和127(或者說(shuō)0x00 ~ 0x1F和0x7F嘹朗,為了放便师妙,后面均使用十進(jìn)制表示)。其余的則是英文標(biāo)點(diǎn)骡显、數(shù)學(xué)運(yùn)算符疆栏、阿拉伯?dāng)?shù)字和大小寫(xiě)拉丁字母(英文字母)。
控制字符是不可顯示的惫谤,但是有些終端已經(jīng)提供了擴(kuò)展壁顶,使得這些字符可顯示為諸如笑臉、撲克牌花式等8-bit符號(hào)溜歪,且這33個(gè)字符多數(shù)都已是陳廢的控制字符若专。

2.2 EASCII

Extended ASCII

ASCII的缺點(diǎn)是只能顯示基本的拉丁字母,阿拉伯?dāng)?shù)字和一些英式標(biāo)點(diǎn)符號(hào)蝴猪,因此只能用于顯示現(xiàn)代美國(guó)英語(yǔ)调衰。所以當(dāng)計(jì)算機(jī)流行到歐洲國(guó)家時(shí),就有了各種各樣的擴(kuò)展ASCII自阱,統(tǒng)稱EASCII嚎莉。它將ASCII擴(kuò)充到一個(gè)字節(jié),8bit沛豌, 一共能表示256個(gè)字符趋箩,向下兼容ASCII。但是很明顯加派,各種EASCII是互不兼容的叫确。
著名的EASCII是IBM的代碼頁(yè)437,是早期IBM-PC使用的編碼系統(tǒng)芍锦。

2.3 ISO/IEC 646

ISO/IEC 代表兩個(gè)組織竹勉,分別是國(guó)際標(biāo)準(zhǔn)化組織International Organization for Standardization和國(guó)際電工委員會(huì)International Electrotechnical Commission。
ISO和IEC什么時(shí)候聯(lián)合成小組的就不知道了娄琉,上面引用的文章中說(shuō)是1984年是錯(cuò)誤的次乓,ISO/IEC 646公布于1972年吓歇,肯定是早于這個(gè)年份才對(duì)。

ISO/IEC在1972年公布了ISO/IEC 646標(biāo)準(zhǔn)票腰,它是一個(gè)7bit字符集照瘾,來(lái)自數(shù)個(gè)國(guó)家國(guó)家標(biāo)準(zhǔn),主要來(lái)自美國(guó)的ASCII丧慈。
可以說(shuō),ASCII等同于ISO/IEC 646主卫。等同于的意思就是大部分相同逃默,少量修改或擴(kuò)展。

而ISO/IEC 646和ASCII主要區(qū)別在于:

  • ISO/IEC 646將ASCII碼中的# $ @ [ \ ] ^ ` { | } ~這12個(gè)碼位去除簇搅,留給其它國(guó)家自己定義完域。
  • 而且ISO/IEC 646規(guī)定,可以將一些標(biāo)點(diǎn)符號(hào)附加在拉丁字母后面瘩将,并且跟上一個(gè)退格符鍵符(backspace吟税,碼位為0x8)),用于表示變音符號(hào)姿现,例如á可以用a/表示肠仪,而編碼中a/后面會(huì)跟著一個(gè)退格鍵符,用于終端識(shí)別這是個(gè)變音符號(hào)备典。

至此异旧,各國(guó)可以根據(jù)ISO/IEC 646產(chǎn)生自己的變體7bit字符集。ASCII也是符合這個(gè)標(biāo)準(zhǔn)的提佣,因?yàn)镮SO/IEC 646本身就是參考自ASCII吮蛹。

2.4 ISO/IEC 2022

ISO 2022可以說(shuō)是字符編碼的里程碑,用了很巧妙的方式統(tǒng)一了混亂的編碼問(wèn)題拌屏,并且提供了多字節(jié)編碼的擴(kuò)充標(biāo)準(zhǔn)潮针。我們熟知的ISO 8859-1,GB2312都是使用這套標(biāo)準(zhǔn)倚喂。
這套標(biāo)準(zhǔn)非常復(fù)雜每篷,下面的解釋可能不太準(zhǔn)確,不過(guò)大概就是這個(gè)意思务唐。

1963年公布的ASCII碼是第一個(gè)得到廣泛采用的7位字符編碼雳攘,這時(shí)的通信領(lǐng)域的協(xié)議采用了第8位做校驗(yàn)糾錯(cuò)用途。但是對(duì)計(jì)算機(jī)內(nèi)存來(lái)說(shuō)枫笛,糾錯(cuò)位不是必要的吨灭,因此8位字符編碼逐漸出現(xiàn),用來(lái)表示比ASCII碼更多的字符刑巧。
而為了8位字符編碼也能使用7比特信道傳輸喧兄,ISO 2022規(guī)定了7位字符集和8位字符集的采用相同的結(jié)構(gòu)无畔,使得它們可以互相轉(zhuǎn)換。并且吠冤,ISO 2022還規(guī)定了多字節(jié)字符編碼的擴(kuò)展方式浑彰,使單字節(jié)和多字節(jié)、7位還和8位拯辙,都能使用同一套編碼解析郭变。而GB2312、ISO 8859-1都是是同這套標(biāo)準(zhǔn)涯保。

ISO 2022標(biāo)準(zhǔn)是怎么兼容7比特信道的呢诉濒?
它可以將任意字節(jié)長(zhǎng)度的字符集,都轉(zhuǎn)換成任意數(shù)量的7bit編碼表夕春。


對(duì)于7位字符編碼未荒,0/0 到 1/15(column/row)是控制字符,一共32個(gè)及志,表示CL(control left)區(qū)域片排。
2/0 到 7/15 是圖形字符,一共94個(gè)(為了兼容ASCII碼表速侈,左上角和右下角被sp空格符和del符占用的碼位留空)率寡,表示GL(graphic left)區(qū)域。

對(duì)于8位字符編碼倚搬,在兼容ASCII的同時(shí)勇劣,還使用到了CR和GR區(qū)域,如下圖潭枣,大家可以找下ISO 8859-1的編碼表對(duì)照下比默,ISO 8859-1也是使用ISO 2022標(biāo)準(zhǔn)的一個(gè)字符編碼系統(tǒng)。

  • CL(0/0?1/15)
  • GL(2/0?7/15)
  • CR(8/0?9/15)
  • GR(10/0?15/15)

控制字符是CL和CR區(qū)域盆犁,圖形字符是GL和GR區(qū)域命咐。
CR和CL位置對(duì)應(yīng),CR的碼位減去160即CL的碼位谐岁,GR和GL同理醋奠,但是GR包含94或者96個(gè)字符,左上角和右下角的空位可以被填充伊佃。

當(dāng)8位字符編碼兼容7bit傳輸信道時(shí)窜司,即:將GR區(qū)域偏移到GL區(qū)域,不過(guò)左上角和右下角的字符可能會(huì)丟失航揉。

而多字節(jié)字符編碼系統(tǒng)塞祈,采用的是區(qū)位表示法,并且是一種變長(zhǎng)編碼帅涂,即可以使用兩個(gè)字節(jié)表示一個(gè)字符议薪,也可以使用一個(gè)字節(jié)表示ASCII字符尤蛮。
例如雙字節(jié)字符編碼,最多可以表示94x94或96x96個(gè)字符斯议。高位字節(jié)用來(lái)表示94個(gè)區(qū)产捞,低位字節(jié)用來(lái)表示每個(gè)區(qū)中的94個(gè)碼位,碼位都是和ASCII碼表的碼位對(duì)應(yīng)的哼御,是為了使用統(tǒng)一的方法解析編碼坯临。
而三字節(jié)編碼,就是可以表示94x94x94個(gè)字符了恋昼,不過(guò)實(shí)際上并沒(méi)有符合ISO 2022標(biāo)準(zhǔn)的三字節(jié)編碼表尿扯。

當(dāng)需要解析某個(gè)字節(jié)時(shí),會(huì)使用到緩沖區(qū)焰雕,一共有6個(gè)緩沖區(qū),C0 C1 G0 G1 G2 G3芳杏,用于動(dòng)態(tài)分配不同的字符集矩屁,每個(gè)緩沖區(qū)用于存儲(chǔ)不同類型的字符集。C0 C1對(duì)應(yīng)控制字符爵赵,G0對(duì)應(yīng)94個(gè)字符的編碼表吝秕,G1對(duì)應(yīng)94x94類型的字符編碼表,G2對(duì)應(yīng)96個(gè)字符的編碼表空幻,G3對(duì)應(yīng)96x96類型的字符編碼表烁峭。如圖


例如用GB2312編碼解析字節(jié)時(shí),將GB2312字符集指派(designate)到G1緩沖區(qū)秕铛,然后調(diào)用到GR區(qū)域约郁,通過(guò)該字節(jié)對(duì)應(yīng)的碼位找到對(duì)應(yīng)字符。
再比如有兩個(gè)字節(jié)但两,10110000 10100001鬓梅,十六進(jìn)制為B0A1,轉(zhuǎn)換成區(qū)位碼(GB2312使用GR區(qū)域谨湘,減去160則是區(qū)位碼)則是第16頁(yè)第1個(gè)字符 “啊”绽快。首先GB2312字符集指派到G1緩沖區(qū),然后通過(guò)某種方式(locking shift)將第16頁(yè)調(diào)用到GR區(qū)域紧阔,然后找到GR區(qū)域的第一個(gè)字符是“啊”坊罢,顯示到屏幕。

而這個(gè)過(guò)程如何指派擅耽,如何調(diào)用是通過(guò)轉(zhuǎn)移序列(escape sequence)控制活孩,轉(zhuǎn)義序列是以ESC字符開(kāi)頭的一系列字節(jié)。這個(gè)說(shuō)起來(lái)有些復(fù)雜乖仇,本身ISO 2022并不是重點(diǎn)诱鞠,這里已經(jīng)講太多了挎挖,有興趣的可以看引用的幾篇文章,推薦ISO 2022 介紹(1): 標(biāo)準(zhǔn)

2.5 ISO/IEC 8859-1

在ISO/IEC 2022發(fā)布后航夺,ISO/IEC也根據(jù)這個(gè)標(biāo)準(zhǔn)制定了一系列的名為ISO/IEC 8859-x的單字節(jié)字符集蕉朵,分別從ISO 8859-1 到 ISO 8859 -16等十幾個(gè)編碼系統(tǒng),提供給各個(gè)地區(qū)使用阳掐。其中由于未知原因始衅,ISO 8859-12并沒(méi)有使用。
其中ISO/IEC 8859-1的流通性最廣缭保,顧而這里使用ISO/IEC 8859-1作為標(biāo)題汛闸。

2.6 GB 2312

GB是國(guó)標(biāo)的拼音首字母。

在ISO/IEC 2022發(fā)布后艺骂,我國(guó)也根據(jù)這個(gè)標(biāo)準(zhǔn)制定了GB 2312標(biāo)準(zhǔn)诸老,全稱《信息交換用漢字編碼字符集·基本集》。于1980年發(fā)布钳恕,1981年5月1日正式實(shí)施别伏。
GB2312是一種可變長(zhǎng)的雙字節(jié)編碼系統(tǒng)(上面就說(shuō)了ISO/IEC 2022S是可變長(zhǎng)的),可以用一個(gè)字節(jié)表示ASCII的字符忧额,用兩個(gè)字節(jié)表示中文或其它字符厘肮。

2.7 BIG5

GB2312只支持簡(jiǎn)體字符,所以GB2312發(fā)布后不久睦番,臺(tái)灣地區(qū)制定了BIG5標(biāo)準(zhǔn)类茂,包括13,053個(gè)字與441個(gè)符號(hào),供港澳臺(tái)地區(qū)使用托嚣。
BIG5并不是按照ISO 2022標(biāo)準(zhǔn)制定的巩检,采用雙字節(jié)編碼方式。

2.8 ISO/IEC 10646 /UCS

ISO 2022是字符編碼領(lǐng)域設(shè)計(jì)最為精巧復(fù)雜的編碼機(jī)制 ,極大地促進(jìn)了各種國(guó)家 /地區(qū)編碼字符集標(biāo)準(zhǔn)的發(fā)展 ,提供了字符集的標(biāo)識(shí)和切換機(jī)制以實(shí)現(xiàn)多語(yǔ)言環(huán)境下的編碼擴(kuò)充 ,使得不同語(yǔ)言文字語(yǔ)境下的信息交換成為可能示启。以 Unix為代表的開(kāi)放系統(tǒng)在實(shí)現(xiàn)中廣泛應(yīng)用了眾多 ISO 2022的派生方案 ,曾一度代表了系統(tǒng)軟件國(guó)際化的前沿水平碴巾。盡管 ISO 2022的主要目標(biāo)是要服務(wù)于多語(yǔ)言環(huán)境 ,但在實(shí)施過(guò)程中暴露出了一些難以解決的問(wèn)題 ,包括 :實(shí)現(xiàn)開(kāi)銷可觀 ,字符集的選擇依賴于環(huán)境 ,需要上層能識(shí)別相應(yīng)字符集等。實(shí)踐說(shuō)明以多個(gè)獨(dú)立編碼字符集為基礎(chǔ)進(jìn)行動(dòng)態(tài)切換的多語(yǔ)言支持方案無(wú)法達(dá)到預(yù)期目標(biāo) ,問(wèn)題的關(guān)鍵是字符編碼只有在一致語(yǔ)境中才能正確解釋 ,包容世界上所有文字的單一編碼字符集才是合理的方案 ,通用字符集 UCS(Universal Character Set)因此應(yīng)運(yùn)而生丑搔。

ISO/IEC 10646標(biāo)準(zhǔn)定義了31位的UCS通用字符集(Universal Coded Character Set)厦瓢,中文譯作“通用多八位編碼字符集”。

ISO/IEC 10646規(guī)定了四個(gè)八位位組 (分別表示組啤月、平面煮仇、行、字位 )構(gòu)成的編碼空間谎仲。一共128個(gè)組浙垫,每個(gè)組256個(gè)平面,每個(gè)平面256行,每行256個(gè)碼位夹姥,全部編碼空間的大小為 2^31杉武。
實(shí)際上目前只用到了第0組中的17個(gè)平面,其中 0平面中碼位被分配給了各種文字的最常用字符 ,稱為基本多文種平面 BMP辙售,而其它平面則稱為輔助平面轻抱。BMP的使用覆蓋率可達(dá)97%

而UCS有兩種編碼方式,分別是UCS-2和UCS-4旦部,UCS-2使用16位編碼空間祈搜,而UCS-4使用32位編碼空間,也就是一個(gè)字符占用兩個(gè)字節(jié)或4個(gè)字節(jié)士八。
而對(duì)于一個(gè)常用平面(BMP)容燕,UCS-2就足夠了,但還想表示其它平面的字符婚度,就需要用到UCS-4了蘸秘。

2.9 Unicode

位于美國(guó)加州的Unicode組織允許任何愿意支付會(huì)費(fèi)的公司和個(gè)人加入,其成員包含了主要的電腦軟硬件廠商蝗茁,例如奧多比系統(tǒng)醋虏、蘋(píng)果公司、惠普评甜、IBM、微軟仔涩、施樂(lè)等忍坷。
20世紀(jì)80年代末,組成Unicode組織的商業(yè)機(jī)構(gòu)熔脂,和國(guó)際合作的國(guó)際標(biāo)準(zhǔn)化組織因?yàn)殡娔X普及和信息國(guó)際化的前提下佩研,分別各自成立了Unicode組織和ISO-10646工作小組。他們不久便發(fā)現(xiàn)對(duì)方的存在霞揉,大家為著相同的目的而工作旬薯。
1991年,Unicode 1.0發(fā)布适秩,包含7,161個(gè)字符绊序,但是不包含CJK(中日韓統(tǒng)一表意文字)字符。
1992年秽荞,Unicode 1.0.1發(fā)布骤公,包含CJK最初的20,902個(gè)字.
1993年,Unicode 1.1發(fā)布扬跋,對(duì)應(yīng)ISO/IEC 10646的最初版本阶捆。
之后的每一個(gè)Unicode版本都對(duì)應(yīng)著相同的ISO/IEC 10646版本,而Unicode1.0和1.0.1的制定有沒(méi)有ISO參與就不清楚了。

Unicode在字符洒试、字符命名倍奢、碼位分配方面和ISO 10646(UCS)是保證一致的,因此兩個(gè)標(biāo)準(zhǔn)在編碼字符集層次上完全等同垒棋,只是 Unicode在此基礎(chǔ)上增加了重要的實(shí)現(xiàn)算法卒煞、字符屬性以及其他語(yǔ)義信息方面的規(guī)定。

當(dāng)然Unicode的編碼方式和UCS是一樣的捕犬,但編碼方式和實(shí)現(xiàn)方式不同跷坝,編碼只是賦予字符一個(gè)編號(hào),而實(shí)現(xiàn)方式則是確確實(shí)實(shí)的將字符轉(zhuǎn)成計(jì)算機(jī)可識(shí)別的二進(jìn)制碉碉,或者說(shuō)定義了Unicode字符在內(nèi)存中怎么存儲(chǔ)柴钻。這些實(shí)現(xiàn)方式叫UTF(Unicode Transformation Format,Unicode 轉(zhuǎn)換格式)垢粮。當(dāng)然贴届,我們也可以直接叫UTF編碼,文章開(kāi)頭就說(shuō)了不要太在意這個(gè)術(shù)語(yǔ)蜡吧,下面就用UTF編碼稱呼毫蚓。

UTF有幾種方式實(shí)現(xiàn):

  • UTF - 32: UTF-32是UTF-*家族中唯一的一個(gè)定長(zhǎng)編碼,使用4個(gè)字節(jié)編碼昔善,和UCS_4是等價(jià)的元潘。它的好處很明顯,不需要什么特殊的算法就可以直接用4個(gè)字節(jié)表示UCS字符集中的字符君仆,二進(jìn)制和USC字符編碼的相同翩概。但是劣勢(shì)更明顯,7位就可以表示的英文字母也消耗4個(gè)字節(jié)的編碼空間返咱。
  • UTF - 16: UTF-16是一種變長(zhǎng)編碼钥庇,最少可以用兩個(gè)字節(jié)來(lái)表示一個(gè)字符,只使用兩個(gè)字節(jié)的時(shí)候咖摹,和UCS_2是等價(jià)的评姨,足夠用于表示第0平面的字符。而對(duì)于輔助平面萤晴,會(huì)通過(guò)某種算法吐句,延長(zhǎng)到4個(gè)字節(jié)來(lái)表示輔助平面的字符。

UTF-16 與 UTF-32 還有一個(gè)不明顯的缺點(diǎn)店读。我們知道不同的計(jì)算機(jī)存儲(chǔ)字節(jié)的順序是不一樣的蕴侧,這也就意味著U+4E2D 在 UTF-16 可以保存為4E 2D,也可以保存成2D 4E两入,這取決于計(jì)算機(jī)是采用大端模式還是小端模式净宵,UTF-32 的情況也類似。為了解決這個(gè)問(wèn)題,引入了 BOM (Byte Order Mark)择葡,它是一特殊的不可見(jiàn)字符紧武,位于文件的起始位置,標(biāo)示該文件的字節(jié)序敏储。對(duì)于 UTF-16 來(lái)說(shuō)阻星,BOM 為U+FEFF(FF 比 FE 大 1),如果 UTF-16 編碼的文件以FF FE開(kāi)始已添,那么就意味著其字節(jié)序?yàn)?strong>小端模式妥箕,如果以FE FF開(kāi)始,那么就是大端模式更舞。
其他 UTF-* 編碼的 BOM 可以參考 Representations of byte order marks by encoding畦幢。

  • UTF - 8:UTF-8可以說(shuō)是我們比較熟悉的一種Unicode編碼實(shí)現(xiàn)方式了,它和UTF - 16一樣缆蝉,是變長(zhǎng)編碼宇葱。不過(guò)它最小可以使用一個(gè)字節(jié)來(lái)表示一個(gè)ASCII字符。對(duì)于擴(kuò)展的ASCII刊头,例如ISO 8859-1黍瞧,會(huì)使用到兩個(gè)字節(jié),對(duì)于BMP(基本多文種平面)則使用到三個(gè)字節(jié)原杂,而輔助平面的字符則會(huì)用到四個(gè)字節(jié)印颤。
    UTF-8的實(shí)現(xiàn)算法基于以下幾個(gè)特點(diǎn):
    • 對(duì)于UTF-8編碼中的任意字節(jié)B,如果B的第一位為0穿肄,則B獨(dú)立的表示一個(gè)字符(ASCII碼)年局;
    • 如果B的第一位為1,第二位為0被碗,則B為一個(gè)多字節(jié)字符中的一個(gè)字節(jié)(非ASCII字符)某宪;
    • 如果B的前兩位為1仿村,第三位為0锐朴,則B為兩個(gè)字節(jié)表示的字符中的第一個(gè)字節(jié);
    • 如果B的前三位為1蔼囊,第四位為0焚志,則B為三個(gè)字節(jié)表示的字符中的第一個(gè)字節(jié);
    • 如果B的前四位為1畏鼓,第五位為0酱酬,則B為四個(gè)字節(jié)表示的字符中的第一個(gè)字節(jié);

因此云矫,對(duì)UTF-8編碼中的任意字節(jié)膳沽,根據(jù)第一位,可判斷是否為ASCII字符;根據(jù)前二位挑社,可判斷該字節(jié)是否為一個(gè)字符編碼的第一個(gè)字節(jié)陨界;根據(jù)前四位(如果前兩位均為1),可確定該字節(jié)為字符編碼的第一個(gè)字節(jié)痛阻,并且可判斷對(duì)應(yīng)的字符由幾個(gè)字節(jié)表示菌瘪;根據(jù)前五位(如果前四位為1),可判斷編碼是否有錯(cuò)誤或數(shù)據(jù)傳輸過(guò)程中是否有錯(cuò)誤阱当。如圖:



通過(guò)這種用最高位bit判斷的方式俏扩,UTF-8 就不存在字節(jié)順序在大小端不同的情況,也就是說(shuō)不需要BOM的(即文件開(kāi)頭有沒(méi)有 U+FEFF)弊添。不過(guò)由于微軟會(huì)在UTF-8的編碼中也加上BOM录淡,為了明確區(qū)分ASCII編碼和UTF-8編碼,但這樣的文件在其它系統(tǒng)中可能會(huì)出現(xiàn)問(wèn)題表箭,所以很多編輯器中可以看到UTF-8分有BOM和無(wú)BOM兩種赁咙。
而UTF-8的優(yōu)勢(shì)非常明顯,對(duì)于存儲(chǔ)ASCII字符非常節(jié)省內(nèi)存免钻,但是如果表示BMP平面的字符彼水,就需要多用到一個(gè)字節(jié),例如中文在UTF-16只要兩個(gè)字節(jié)极舔,在UTF-8需要三個(gè)字節(jié)凤覆。

還有UTF-1,UTF-7等不太常用這里不作說(shuō)明拆魏。
而我國(guó)還有個(gè)GB18030盯桦,完全兼容GB2312,基本兼容GBK渤刃,剩余的碼位可以通過(guò)偏移得到Unicode的碼位拥峦,也可以算是一種UTF(Unicode的變換格式)。

2.10 GB 13000

《信息技術(shù) 通用多八位編碼字符集(UCS)第一部分:體系結(jié)構(gòu)與基本多文種平面》

等同于ISO/IEC 10646:1993卖子,說(shuō)白了略号,GB13000實(shí)際上就是UCS的BMP平面,其實(shí)也就是Unicode1.1洋闽。

2.11 GBK

另外再說(shuō)下我們熟知的GBK玄柠,它是對(duì)GB2312的擴(kuò)充,K就是“擴(kuò)”的拼音首字母诫舅,它兼容GB2312羽利,但是并不是使用ISO 2022標(biāo)準(zhǔn)的。
它實(shí)際上是微軟的CP936編碼表刊懈,最早出現(xiàn)在windows95中这弧。將GB13000的全部字符填充到GB2312的空碼位上娃闲。雖然它包含GB13000的全部字符,但它并不兼容Unicode匾浪。

3. 總結(jié)

說(shuō)那么多可能有點(diǎn)亂畜吊,這里總結(jié)下常用的一些字符編碼。

  • ASCII:美國(guó)信息交換標(biāo)準(zhǔn)代碼户矢,一共包含128個(gè)字符玲献,其中33個(gè)控制字符,33個(gè)英文標(biāo)點(diǎn)梯浪,10個(gè)阿拉伯?dāng)?shù)字和52個(gè)大小寫(xiě)拉丁字母捌年。用7位編碼空間即可表示,占用一個(gè)字節(jié)挂洛,第8位在早期用來(lái)糾錯(cuò)礼预,可以百度“校驗(yàn)位”。

  • ISO-8859-1:使用最多的ISO 2022標(biāo)準(zhǔn)的字符集虏劲,使用8位編碼空間托酸,占用一個(gè)字節(jié)兄春。

  • GB2312:我國(guó)發(fā)表的符合ISO 2022標(biāo)準(zhǔn)的字符集耀盗,使用到區(qū)位碼的方式編碼,一共94個(gè)區(qū)窝革,每個(gè)區(qū)94個(gè)碼位堡掏,為了兼容ASCII碼表应结,碼位均分布在GR區(qū)(160~255)。一共包含漢字6763個(gè)和非漢字圖形字符682個(gè)泉唁。部分區(qū)位沒(méi)有使用

  • GBK:微軟擴(kuò)展的GB2312鹅龄,收錄了GB13000的所有字符(或者說(shuō)unicode1.1)。填充到GB2312空白的區(qū)位上亭畜,兼容GB2312扮休,但是不兼容Unicode。
    GBK的K代表中文的“擴(kuò)”拴鸵,GBK并不屬于國(guó)家標(biāo)準(zhǔn)玷坠,而是一個(gè)“技術(shù)規(guī)范指導(dǎo)性文件”,它的前身其實(shí)是微軟windows95上的cp936編碼宝踪。

  • UCS:ISO 10646定義的字符集侨糟,擁有31位編碼空間碍扔,4個(gè)字節(jié)分別代表126個(gè)組瘩燥,每組256個(gè)平面,每個(gè)平面256頁(yè)不同,每頁(yè)256個(gè)字符厉膀。和Unicode同步發(fā)展溶耘,目前定義了17個(gè)平面,第0平面稱為基本多文種平面(BMP)服鹅,包含所有的常用字符凳兵,其余的16個(gè)平面稱為輔助平面。
    而UCS的編碼分為UCS_2和UCS_4兩種企软,UCS_2使用兩個(gè)字節(jié)庐扫,只能編碼基本多文種平面的字符。而UCS_4使用四個(gè)字節(jié)仗哨,可以編碼所有平面形庭。

  • Unicode:和UCS同步發(fā)展,和UCS使用相同的字符集厌漂,但是額外定義了編碼的實(shí)現(xiàn)方式萨醒,稱為UTF(Unicode轉(zhuǎn)換格式, Unicode Transformation Format)苇倡,而常用的UTF有UTF-32富纸,UTF-16,UTF-8旨椒。

  • UTF-32:和UCS_4編碼一樣晓褪,采用4字節(jié)編碼,是一種定長(zhǎng)編碼方式综慎,即ASCII的7位編碼空間的字符也一律使用4字節(jié)編碼辞州。另外,由于計(jì)算機(jī)系統(tǒng)分為大端模式和小端模式寥粹,二進(jìn)制的排列方式相反变过,不同順序編碼會(huì)得到不同字符。所以需要用一個(gè)特殊的不可見(jiàn)字符在文件開(kāi)頭來(lái)標(biāo)記順序涝涤,U+FFEF表示大端模式媚狰,U+FEFF表示小端模式。而這兩個(gè)字不可見(jiàn)字符稱為BOM(Byte Order Mark)阔拳。

  • UTF-16:和UCS_2編碼一樣崭孤,采用2字節(jié)編碼,單它是一種變長(zhǎng)的編碼方式糊肠,如果要表示輔助平面的字符辨宠,可以變長(zhǎng)到4個(gè)字節(jié)變編碼,和UTF-32一樣货裹,需要BOM嗤形。

  • UTF-8:一種變長(zhǎng)編碼方式,用開(kāi)始字節(jié)的最高位來(lái)判斷字符的占用字節(jié)弧圆,具體規(guī)則看上文赋兵。最低可以用1個(gè)字節(jié)來(lái)表示ASCII編碼字符笔咽,兩個(gè)字節(jié)表示EASCII的編碼字符(例如ISO 8859-1),3個(gè)字節(jié)表示基本多文種平面的字符霹期,4個(gè)字節(jié)表示其它輔助平面的字符叶组。
    UTF-8是不需要BOM的,通過(guò)高位字節(jié)即可確定編碼順序历造,但是因?yàn)闅v史遺留原因甩十,Windos系統(tǒng)一般也給UTF-8加上BOM標(biāo)識(shí)以便明確區(qū)分Unicode和其它代碼頁(yè),所以一些編輯器上可以看到UTF-8分為有BOM和無(wú)BOM兩種吭产。

4. 猝

上次寫(xiě)完閉包的文章之后枣氧,決定不再糾結(jié)這種問(wèn)題,結(jié)果還是陷進(jìn)來(lái)了垮刹,幾分鐘能簡(jiǎn)單了解的知識(shí)點(diǎn)硬生生擴(kuò)充到使用幾天來(lái)寫(xiě)一篇文章……
不過(guò)確實(shí)懂了好多東西=达吞。=,另外鄙視以下百度荒典,基本搜不出你想要的東西酪劫,推薦科學(xué)上網(wǎng)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末寺董,一起剝皮案震驚了整個(gè)濱河市覆糟,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌遮咖,老刑警劉巖滩字,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異御吞,居然都是意外死亡麦箍,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)陶珠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)挟裂,“玉大人,你說(shuō)我怎么就攤上這事揍诽【魅兀” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵暑脆,是天一觀的道長(zhǎng)渠啤。 經(jīng)常有香客問(wèn)我,道長(zhǎng)添吗,這世上最難降的妖魔是什么沥曹? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮根资,結(jié)果婚禮上架专,老公的妹妹穿的比我還像新娘。我一直安慰自己玄帕,他們只是感情好部脚,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著裤纹,像睡著了一般委刘。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上鹰椒,一...
    開(kāi)封第一講書(shū)人閱讀 51,679評(píng)論 1 305
  • 那天锡移,我揣著相機(jī)與錄音,去河邊找鬼漆际。 笑死淆珊,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的奸汇。 我是一名探鬼主播施符,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼擂找!你這毒婦竟也來(lái)了戳吝?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤贯涎,失蹤者是張志新(化名)和其女友劉穎听哭,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體塘雳,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡陆盘,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了败明。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片礁遣。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖肩刃,靈堂內(nèi)的尸體忽然破棺而出祟霍,到底是詐尸還是另有隱情,我是刑警寧澤盈包,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布沸呐,位于F島的核電站,受9級(jí)特大地震影響呢燥,放射性物質(zhì)發(fā)生泄漏崭添。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一叛氨、第九天 我趴在偏房一處隱蔽的房頂上張望呼渣。 院中可真熱鬧棘伴,春花似錦、人聲如沸屁置。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)蓝角。三九已至阱穗,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間使鹅,已是汗流浹背揪阶。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留患朱,地道東北人鲁僚。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像裁厅,于是被迫代替她去往敵國(guó)和親蕴茴。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 原文在這里:各種字符集和編碼詳解 在軟件的編碼和實(shí)現(xiàn)中姐直,我們可能會(huì)碰到個(gè) 一個(gè)比較頭疼的問(wèn)題--編碼倦淀,不同字符間的...
    舌尖上的大胖閱讀 1,795評(píng)論 0 2
  • 字符是用戶可以讀寫(xiě)的最小單位撞叽。計(jì)算機(jī)所能支持的字符組成的集合,就叫做字符集插龄。字符集通常以二維表的形式存在愿棋。二維表的...
    劉惜有閱讀 8,116評(píng)論 2 14
  • 什么是字符集糠雨,什么是字符編碼,它做什么用徘跪? 字符(Charcter)是文字與符號(hào)的總稱甘邀,包括文字、圖形符號(hào)垮庐、數(shù)學(xué)符...
    laravel閱讀 312評(píng)論 0 0
  • 我想我再也不會(huì)回到那里哨查,因?yàn)槟抢餂](méi)有你逗抑。 我炒了一盤(pán)洋蔥,淚流滿面。 好想回到小時(shí)候邮府,回到有你的日子荧关,不再長(zhǎng)...
    單小白閱讀 217評(píng)論 0 2
  • 今天病得有點(diǎn)不知所措,先是喉嚨癢褂傀,接著是鼻涕不止忍啤,發(fā)展到現(xiàn)在就是頭暈?zāi)X脹四肢無(wú)力… 真是病來(lái)如山倒啊,沒(méi)辦法沉下心...
    猛虎哥閱讀 140評(píng)論 0 1