字符編碼技術(shù)專題(一):快速理解ASCII、Unicode、GBK和UTF-8

本文由阮一峰(ruanyifeng.com)分享,本文收錄時(shí)有內(nèi)容修訂和排版優(yōu)化。
1、引言
今天中午,我突然想搞清楚 Unicode 和 UTF-8 之間的關(guān)系,就開(kāi)始查資料。
這個(gè)問(wèn)題比我想象的復(fù)雜,午飯后一直看到晚上9點(diǎn),才算初步搞清楚。
下面就是我的總結(jié),主要用來(lái)整理自己的思路。我盡量寫(xiě)得通俗易懂,希望能對(duì)其他朋友有用。畢竟,字符編碼是計(jì)算機(jī)技術(shù)的基石,對(duì)于程序員來(lái)說(shuō)尤其重要,字符編碼的知識(shí)是必須要懂的。
?
技術(shù)交流:
- 移動(dòng)端IM開(kāi)發(fā)入門(mén)文章:《新手入門(mén)一篇就夠:從零開(kāi)發(fā)移動(dòng)端IM》
- 開(kāi)源IM框架源碼:https://github.com/JackJiang2011/MobileIMSDK(備用地址點(diǎn)此)
(本文已同步發(fā)布于:http://www.52im.net/thread-4433-1-1.html)
2、專題目錄
本文是“字符編碼技術(shù)專題”系列文章的第?1?篇,總目錄如下:
《字符編碼技術(shù)專題(一):快速理解ASCII、Unicode、GBK和UTF-8》(* 本文)
《字符編碼技術(shù)專題(二):史詩(shī)級(jí)計(jì)算機(jī)字符編碼知識(shí)入門(mén),一文即懂!》
《字符編碼技術(shù)專題(三):徹底搞懂字符亂碼的本質(zhì),一篇就夠!》
《字符編碼技術(shù)專題(四):史上最通俗大小端字節(jié)序詳解,一文即懂!》
《字符編碼技術(shù)專題(五):前端必讀的計(jì)算機(jī)字符編碼知識(shí)入門(mén)》
3、基礎(chǔ)知識(shí)
計(jì)算機(jī)中儲(chǔ)存的信息都是用二進(jìn)制數(shù)表示的;而我們?cè)谄聊簧峡吹降挠⑽?、漢字等字符是二進(jìn)制數(shù)轉(zhuǎn)換之后的結(jié)果。通俗的說(shuō),按照何種規(guī)則將字符存儲(chǔ)在計(jì)算機(jī)中,如'a'用什么表示,稱為"編碼";反之,將存儲(chǔ)在計(jì)算機(jī)中的二進(jìn)制數(shù)解析顯示出來(lái),稱為"解碼",如同密碼學(xué)中的加密和解密。在解碼過(guò)程中,如果使用了錯(cuò)誤的解碼規(guī)則,則導(dǎo)致'a'解析成'b'或者亂碼。
字符集(Charset):是一個(gè)系統(tǒng)支持的所有抽象字符的集合。字符是各種文字和符號(hào)的總稱,包括各國(guó)家文字、標(biāo)點(diǎn)符號(hào)、圖形符號(hào)、數(shù)字等。
字符編碼(Character Encoding):是一套法則,使用該法則能夠?qū)ψ匀徽Z(yǔ)言的字符的一個(gè)集合(如字母表或音節(jié)表),與其他東西的一個(gè)集合(如號(hào)碼或電脈沖)進(jìn)行配對(duì)。即在符號(hào)集合與數(shù)字系統(tǒng)之間建立對(duì)應(yīng)關(guān)系,它是信息處理的一項(xiàng)*本技術(shù)。通常人們用符號(hào)集合(一般情況下就是文字)來(lái)表達(dá)信息。而以計(jì)算機(jī)為*礎(chǔ)的信息處理系統(tǒng)則是利用元件(硬件)不同狀態(tài)的組合來(lái)存儲(chǔ)和處理信息的。元件不同狀態(tài)的組合能代表數(shù)字系統(tǒng)的數(shù)字,因此字符編碼就是將符號(hào)轉(zhuǎn)換為計(jì)算機(jī)可以接受的數(shù)字系統(tǒng)的數(shù),稱為數(shù)字代碼。
常見(jiàn)字符集名稱:ASCII字符集、GB2312字符集、BIG5字符集、GB18030字符集、Unicode字符集等。計(jì)算機(jī)要準(zhǔn)確的處理各種字符集文字,需要進(jìn)行字符編碼,以便計(jì)算機(jī)能夠識(shí)別和存儲(chǔ)各種文字。
4、ASCII 碼
我們知道,計(jì)算機(jī)內(nèi)部,所有信息最終都是一個(gè)二進(jìn)制值。每一個(gè)二進(jìn)制位(bit)有0和1兩種狀態(tài),因此八個(gè)二進(jìn)制位就可以組合出256種狀態(tài),這被稱為一個(gè)字節(jié)(byte)。也就是說(shuō),一個(gè)字節(jié)一共可以用來(lái)表示256種不同的狀態(tài),每一個(gè)狀態(tài)對(duì)應(yīng)一個(gè)符號(hào),就是256個(gè)符號(hào),從00000000到11111111。
上個(gè)世紀(jì)60年代,美國(guó)制定了一套字符編碼,對(duì)英語(yǔ)字符與二進(jìn)制位之間的關(guān)系,做了統(tǒng)一規(guī)定。這被稱為 ASCII 碼,一直沿用至今。
ASCII 碼一共規(guī)定了128個(gè)字符的編碼,比如空格SPACE是32(二進(jìn)制00100000),大寫(xiě)的字母A是65(二進(jìn)制01000001)。這128個(gè)符號(hào)(包括32個(gè)不能打印出來(lái)的控制符號(hào)),只占用了一個(gè)字節(jié)的后面7位,最前面的一位統(tǒng)一規(guī)定為0。

▲ ASCII編碼表
5、非 ASCII 編碼
英語(yǔ)用128個(gè)符號(hào)編碼就夠了,但是用來(lái)表示其他語(yǔ)言,128個(gè)符號(hào)是不夠的。比如,在法語(yǔ)中,字母上方有注音符號(hào),它就無(wú)法用 ASCII 碼表示。于是,一些歐洲國(guó)家就決定,利用字節(jié)中閑置的最高位編入新的符號(hào)。比如,法語(yǔ)中的é的編碼為130(二進(jìn)制10000010)。這樣一來(lái),這些歐洲國(guó)家使用的編碼體系,可以表示最多256個(gè)符號(hào)。

▲ 擴(kuò)展ASCII編碼表
但是,這里又出現(xiàn)了新的問(wèn)題。不同的國(guó)家有不同的字母,因此,哪怕它們都使用256個(gè)符號(hào)的編碼方式,代表的字母卻不一樣。比如,130在法語(yǔ)編碼中代表了é,在希伯來(lái)語(yǔ)編碼中卻代表了字母Gimel (?),在俄語(yǔ)編碼中又會(huì)代表另一個(gè)符號(hào)。但是不管怎樣,所有這些編碼方式中,0--127表示的符號(hào)是一樣的,不一樣的只是128--255的這一段。
至于亞洲國(guó)家的文字,使用的符號(hào)就更多了,漢字就多達(dá)10萬(wàn)左右。一個(gè)字節(jié)只能表示256種符號(hào),肯定是不夠的,就必須使用多個(gè)字節(jié)表達(dá)一個(gè)符號(hào)。比如,簡(jiǎn)體中文常見(jiàn)的編碼方式是 GB2312,使用兩個(gè)字節(jié)表示一個(gè)漢字,所以理論上最多可以表示 256 x 256 = 65536 個(gè)符號(hào)。
中文編碼的問(wèn)題比較復(fù)雜,將在文末討論。這里先了解下,雖然都是用多個(gè)字節(jié)表示一個(gè)符號(hào),但是GB類的漢字編碼與后文的 Unicode 和 UTF-8 是毫無(wú)關(guān)系的。
6、Unicode
正如上一節(jié)所說(shuō),世界上存在著多種編碼方式,同一個(gè)二進(jìn)制數(shù)字可以被解釋成不同的符號(hào)。因此,要想打開(kāi)一個(gè)文本文件,就必須知道它的編碼方式,否則用錯(cuò)誤的編碼方式解讀,就會(huì)出現(xiàn)亂碼。為什么電子郵件常常出現(xiàn)亂碼?就是因?yàn)榘l(fā)信人和收信人使用的編碼方式不一樣。
可以想象,如果有一種編碼,將世界上所有的符號(hào)都納入其中。每一個(gè)符號(hào)都給予一個(gè)獨(dú)一無(wú)二的編碼,那么亂碼問(wèn)題就會(huì)消失。這就是 Unicode,就像它的名字都表示的,這是一種所有符號(hào)的編碼。
Unicode 當(dāng)然是一個(gè)很大的集合,現(xiàn)在的規(guī)??梢匀菁{100多萬(wàn)個(gè)符號(hào)。每個(gè)符號(hào)的編碼都不一樣,比如,U+0639表示阿拉伯字母Ain,U+0041表示英語(yǔ)的大寫(xiě)字母A,U+4E25表示漢字嚴(yán)。具體的符號(hào)對(duì)應(yīng)表,可以查詢unicode.org,或者專門(mén)的漢字對(duì)應(yīng)表。
7、Unicode 的問(wèn)題
需要注意的是,Unicode 只是一個(gè)符號(hào)集,它只規(guī)定了符號(hào)的二進(jìn)制代碼,卻沒(méi)有規(guī)定這個(gè)二進(jìn)制代碼應(yīng)該如何存儲(chǔ)。
比如,漢字嚴(yán)的 Unicode 是十六進(jìn)制數(shù)4E25,轉(zhuǎn)換成二進(jìn)制數(shù)足足有15位(100111000100101),也就是說(shuō),這個(gè)符號(hào)的表示至少需要2個(gè)字節(jié)。表示其他更大的符號(hào),可能需要3個(gè)字節(jié)或者4個(gè)字節(jié),甚至更多。
這里就有兩個(gè)嚴(yán)重的問(wèn)題,第一個(gè)問(wèn)題是,如何才能區(qū)別 Unicode 和 ASCII ?計(jì)算機(jī)怎么知道三個(gè)字節(jié)表示一個(gè)符號(hào),而不是分別表示三個(gè)符號(hào)呢?第二個(gè)問(wèn)題是,我們已經(jīng)知道,英文字母只用一個(gè)字節(jié)表示就夠了,如果 Unicode 統(tǒng)一規(guī)定,每個(gè)符號(hào)用三個(gè)或四個(gè)字節(jié)表示,那么每個(gè)英文字母前都必然有二到三個(gè)字節(jié)是0,這對(duì)于存儲(chǔ)來(lái)說(shuō)是極大的浪費(fèi),文本文件的大小會(huì)因此大出二三倍,這是無(wú)法接受的。
它們?cè)斐傻慕Y(jié)果是:1)出現(xiàn)了 Unicode 的多種存儲(chǔ)方式,也就是說(shuō)有許多種不同的二進(jìn)制格式,可以用來(lái)表示 Unicode。2)Unicode 在很長(zhǎng)一段時(shí)間內(nèi)無(wú)法推廣,直到互聯(lián)網(wǎng)的出現(xiàn)。
8、UTF-8
互聯(lián)網(wǎng)的普及,強(qiáng)烈要求出現(xiàn)一種統(tǒng)一的編碼方式。UTF-8 就是在互聯(lián)網(wǎng)上使用最廣的一種 Unicode 的實(shí)現(xiàn)方式。其他實(shí)現(xiàn)方式還包括 UTF-16(字符用兩個(gè)字節(jié)或四個(gè)字節(jié)表示)和 UTF-32(字符用四個(gè)字節(jié)表示),不過(guò)在互聯(lián)網(wǎng)上*本不用。重復(fù)一遍,這里的關(guān)系是,UTF-8 是 Unicode 的實(shí)現(xiàn)方式之一。
UTF-8 最大的一個(gè)特點(diǎn),就是它是一種變長(zhǎng)的編碼方式。它可以使用1~4個(gè)字節(jié)表示一個(gè)符號(hào),根據(jù)不同的符號(hào)而變化字節(jié)長(zhǎng)度。
UTF-8 的編碼規(guī)則很簡(jiǎn)單,只有二條:
1)對(duì)于單字節(jié)的符號(hào):字節(jié)的第一位設(shè)為0,后面7位為這個(gè)符號(hào)的 Unicode 碼。因此對(duì)于英語(yǔ)字母,UTF-8 編碼和 ASCII 碼是相同的;
2)對(duì)于n字節(jié)的符號(hào)(n > 1):第一個(gè)字節(jié)的前n位都設(shè)為1,第n + 1位設(shè)為0,后面字節(jié)的前兩位一律設(shè)為10。剩下的沒(méi)有提及的二進(jìn)制位,全部為這個(gè)符號(hào)的 Unicode 碼。
下表總結(jié)了編碼規(guī)則,字母x表示可用編碼的位:

跟據(jù)上表,解讀 UTF-8 編碼非常簡(jiǎn)單。如果一個(gè)字節(jié)的第一位是0,則這個(gè)字節(jié)單獨(dú)就是一個(gè)字符;如果第一位是1,則連續(xù)有多少個(gè)1,就表示當(dāng)前字符占用多少個(gè)字節(jié)。
下面,還是以漢字嚴(yán)為例,演示如何實(shí)現(xiàn) UTF-8 編碼。
嚴(yán)的 Unicode 是4E25(100111000100101),根據(jù)上表,可以發(fā)現(xiàn)4E25處在第三行的范圍內(nèi)(0000 0800 - 0000 FFFF),因此嚴(yán)的 UTF-8 編碼需要三個(gè)字節(jié),即格式是1110xxxx 10xxxxxx 10xxxxxx。然后,從嚴(yán)的最后一個(gè)二進(jìn)制位開(kāi)始,依次從后向前填入格式中的x,多出的位補(bǔ)0。這樣就得到了,嚴(yán)的 UTF-8 編碼是11100100 10111000 10100101,轉(zhuǎn)換成十六進(jìn)制就是E4B8A5。
9、Unicode 與 UTF-8 之間的轉(zhuǎn)換
通過(guò)上一節(jié)的例子,可以看到嚴(yán)的 Unicode碼 是4E25,UTF-8 編碼是E4B8A5,兩者是不一樣的。它們之間的轉(zhuǎn)換可以通過(guò)程序?qū)崿F(xiàn)。
Windows平臺(tái),有一個(gè)最簡(jiǎn)單的轉(zhuǎn)化方法,就是使用內(nèi)置的記事本小程序notepad.exe。打開(kāi)文件后,點(diǎn)擊文件菜單中的另存為命令,會(huì)跳出一個(gè)對(duì)話框,在最底部有一個(gè)編碼的下拉條。

里面有四個(gè)選項(xiàng):ANSI,Unicode,Unicode big endian和UTF-8
1)ANSI是默認(rèn)的編碼方式:對(duì)于英文文件是ASCII編碼,對(duì)于簡(jiǎn)體中文文件是GB2312編碼(只針對(duì) Windows 簡(jiǎn)體中文版,如果是繁體中文版會(huì)采用 Big5 碼);
2)Unicode編碼這里指的是notepad.exe使用的 UCS-2 編碼方式:即直接用兩個(gè)字節(jié)存入字符的 Unicode 碼,這個(gè)選項(xiàng)用的 little endian 格式;
3)Unicode big endian編碼與上一個(gè)選項(xiàng)相對(duì)應(yīng):我在下一節(jié)會(huì)解釋 little endian 和 big endian 的涵義;
4)UTF-8編碼:也就是上一節(jié)談到的編碼方法。
選擇完"編碼方式"后,點(diǎn)擊"保存"按鈕,文件的編碼方式就立刻轉(zhuǎn)換好了。
10、Little endian 和 Big endian
上一節(jié)已經(jīng)提到,UCS-2 格式可以存儲(chǔ) Unicode 碼(碼點(diǎn)不超過(guò)0xFFFF)。以漢字嚴(yán)為例,Unicode 碼是4E25,需要用兩個(gè)字節(jié)存儲(chǔ),一個(gè)字節(jié)是4E,另一個(gè)字節(jié)是25。存儲(chǔ)的時(shí)候,4E在前,25在后,這就是 Big endian 方式;25在前,4E在后,這是 Little endian 方式。
這兩個(gè)古怪的名稱來(lái)自英國(guó)作家斯威夫特的《格列佛游記》。在該書(shū)中,小人國(guó)里爆發(fā)了內(nèi)戰(zhàn),戰(zhàn)爭(zhēng)起因是人們爭(zhēng)論,吃雞蛋時(shí)究竟是從大頭(Big-endian)敲開(kāi)還是從小頭(Little-endian)敲開(kāi)。為了這件事情,前后爆發(fā)了六次戰(zhàn)爭(zhēng),一個(gè)皇帝送了命,另一個(gè)皇帝丟了王位。
第一個(gè)字節(jié)在前,就是"大頭方式"(Big endian),第二個(gè)字節(jié)在前就是"小頭方式"(Little endian)。
那么很自然的,就會(huì)出現(xiàn)一個(gè)問(wèn)題:計(jì)算機(jī)怎么知道某一個(gè)文件到底采用哪一種方式編碼?
Unicode 規(guī)范定義,每一個(gè)文件的最前面分別加入一個(gè)表示編碼順序的字符,這個(gè)字符的名字叫做"零寬度非換行空格"(zero width no-break space),用FEFF表示。這正好是兩個(gè)字節(jié),而且FF比FE大1。
如果一個(gè)文本文件的頭兩個(gè)字節(jié)是FE FF,就表示該文件采用大頭方式;如果頭兩個(gè)字節(jié)是FF FE,就表示該文件采用小頭方式。
11、實(shí)例講解
下面,舉一個(gè)實(shí)例。
打開(kāi)"記事本"程序notepad.exe,新建一個(gè)文本文件,內(nèi)容就是一個(gè)嚴(yán)字,依次采用ANSI,Unicode,Unicode big endian和UTF-8編碼方式保存。
然后,用文本編輯軟件UltraEdit 中的"十六進(jìn)制功能",觀察該文件的內(nèi)部編碼方式:
1)ANSI:文件的編碼就是兩個(gè)字節(jié)D1 CF,這正是嚴(yán)的 GB2312 編碼,這也暗示 GB2312 是采用大頭方式存儲(chǔ)的。
2)Unicode:編碼是四個(gè)字節(jié)FF FE 25 4E,其中FF FE表明是小頭方式存儲(chǔ),真正的編碼是4E25。
3)Unicode big endian:編碼是四個(gè)字節(jié)FE FF 4E 25,其中FE FF表明是大頭方式存儲(chǔ)。
4)UTF-8:編碼是六個(gè)字節(jié)EF BB BF E4 B8 A5,前三個(gè)字節(jié)EF BB BF表示這是UTF-8編碼,后三個(gè)E4B8A5就是嚴(yán)的具體編碼,它的存儲(chǔ)順序與編碼順序是一致的。
UltraEdit下載地址請(qǐng)至官網(wǎng):https://www.ultraedit.com/

▲ UltraEdit軟件
12、最后簡(jiǎn)要看看中文字符集和編碼
12.1GB系列字符集&編碼
計(jì)算機(jī)發(fā)明之處及后面很長(zhǎng)一段時(shí)間,只用應(yīng)用于美國(guó)及西方一些發(fā)達(dá)國(guó)家,ASCII能夠很好滿足用戶的需求。但是當(dāng)天朝也有了計(jì)算機(jī)之后,為了顯示中文,必須設(shè)計(jì)一套編碼規(guī)則用于將漢字轉(zhuǎn)換為計(jì)算機(jī)可以接受的數(shù)字系統(tǒng)的數(shù)。
天朝專家把那些127號(hào)之后的奇異符號(hào)們(即EASCII)取消掉,規(guī)定:一個(gè)小于127的字符的意義與原來(lái)相同,但兩個(gè)大于127的字符連在一起時(shí),就表示一個(gè)漢字,前面的一個(gè)字節(jié)(他稱之為高字節(jié))從0xA1用到 0xF7,后面一個(gè)字節(jié)(低字節(jié))從0xA1到0xFE,這樣我們就可以組合出大約7000多個(gè)簡(jiǎn)體漢字了。在這些編碼里,還把數(shù)學(xué)符號(hào)、羅馬希臘的 字母、日文的假名們都編進(jìn)去了,連在ASCII里本來(lái)就有的數(shù)字、標(biāo)點(diǎn)、字母都統(tǒng)統(tǒng)重新編了兩個(gè)字節(jié)長(zhǎng)的編碼,這就是常說(shuō)的"全角"字符,而原來(lái)在127號(hào)以下的那些就叫"半角"字符了。
上述編碼規(guī)則就是GB2312。GB2312或GB2312-80是中國(guó)國(guó)家標(biāo)準(zhǔn)簡(jiǎn)體中文字符集,全稱《信息交換用漢字編碼字符集·*本集》,又稱GB0,由中國(guó)國(guó)家標(biāo)準(zhǔn)總局發(fā)布,1981年5月1日實(shí)施。GB2312編碼通行于中國(guó)大陸;新加坡等地也采用此編碼。中國(guó)大陸幾乎所有的中文系統(tǒng)和國(guó)際化的軟件都支持GB2312。GB2312的出現(xiàn),*本滿足了漢字的計(jì)算機(jī)處理需要,它所收錄的漢字已經(jīng)覆蓋中國(guó)大陸99.75%的使用頻率。對(duì)于人名、古漢語(yǔ)等方面出現(xiàn)的罕用字,GB2312不能處理,這導(dǎo)致了后來(lái)GBK及GB 18030漢字字符集的出現(xiàn)。下圖是GB2312編碼的開(kāi)始部分(由于其非常龐大,只列舉開(kāi)始部分,具體可查看GB2312簡(jiǎn)體中文編碼表)。

▲ GB2312編碼表的開(kāi)始部分
由于GB 2312-80只收錄6763個(gè)漢字,有不少漢字,如部分在GB 2312-80推出以后才簡(jiǎn)化的漢字(如"啰"),部分人名用字(如中國(guó)前總理***的"*"字),臺(tái)灣及香港使用的繁體字,日語(yǔ)及朝鮮語(yǔ)漢字等,并未有收錄在內(nèi)。于是廠商微軟利用GB 2312-80未使用的編碼空間,收錄GB 13000.1-93全部字符制定了GBK編碼。根據(jù)微軟資料,GBK是對(duì)GB2312-80的擴(kuò)展,也就是CP936字碼表 (Code Page 936)的擴(kuò)展(之前CP936和GB 2312-80一模一樣),最早實(shí)現(xiàn)于Windows 95簡(jiǎn)體中文版。雖然GBK收錄GB 13000.1-93的全部字符,但編碼方式并不相同。GBK自身并非國(guó)家標(biāo)準(zhǔn),只是曾由國(guó)家技術(shù)監(jiān)督局標(biāo)準(zhǔn)化司、電子工業(yè)部科技與質(zhì)量監(jiān)督司公布為"技術(shù)規(guī)范指導(dǎo)性文件"。原始GB13000一直未被業(yè)界采用,后續(xù)國(guó)家標(biāo)準(zhǔn)GB18030技術(shù)上兼容GBK而非GB13000。
GB 18030,全稱:國(guó)家標(biāo)準(zhǔn)GB 18030-2005《信息技術(shù) 中文編碼字符集》,是中華人民共和國(guó)現(xiàn)時(shí)最新的內(nèi)碼字集,是GB 18030-2000《信息技術(shù) 信息交換用漢字編碼字符集 *本集的擴(kuò)充》的修訂版。與GB 2312-1980完全兼容,與GBK*本兼容,支持GB 13000及Unicode的全部統(tǒng)一漢字,共收錄漢字70244個(gè)。
GB 18030主要有以下特點(diǎn):
與UTF-8相同,采用多字節(jié)編碼,每個(gè)字可以由1個(gè)、2個(gè)或4個(gè)字節(jié)組成;
編碼空間龐大,最多可定義161萬(wàn)個(gè)字符;
支持中國(guó)國(guó)內(nèi)少數(shù)民族的文字,不需要?jiǎng)佑迷熳謪^(qū);
漢字收錄范圍包含繁體漢字以及日韓漢字。

▲ GB18030編碼總體結(jié)構(gòu)
本規(guī)格的初版使中華人民共和國(guó)信息產(chǎn)業(yè)部電子工業(yè)標(biāo)準(zhǔn)化研究所起草,由國(guó)家質(zhì)量技術(shù)監(jiān)督局于2000年3月17日發(fā)布?,F(xiàn)行版本為國(guó)家質(zhì)量監(jiān)督檢驗(yàn)總局和中國(guó)國(guó)家標(biāo)準(zhǔn)化管理委員會(huì)于2005年11月8日發(fā)布,2006年5月1日實(shí)施。此規(guī)格為在中國(guó)境內(nèi)所有軟件產(chǎn)品支持的強(qiáng)制規(guī)格。
12.2BIG5字符集&編碼
Big5,又稱為大五碼或五大碼,是使用繁體中文(正體中文)社區(qū)中最常用的電腦漢字字符集標(biāo)準(zhǔn),共收錄13,060個(gè)漢字。中文碼分為內(nèi)碼及交換碼兩類,Big5屬中文內(nèi)碼,知名的中文交換碼有CCCII、CNS11643。Big5雖普及于臺(tái)灣、香港與澳門(mén)等繁體中文通行區(qū),但長(zhǎng)期以來(lái)并非當(dāng)?shù)氐膰?guó)家標(biāo)準(zhǔn),而只是業(yè)界標(biāo)準(zhǔn)。倚天中文系統(tǒng)、Windows等主要系統(tǒng)的字符集都是以Big5為*準(zhǔn),但廠商又各自增加不同的造字與造字區(qū),派生成多種不同版本。2003年,Big5被收錄到CNS11643中文標(biāo)準(zhǔn)交換碼的附錄當(dāng)中,取得了較正式的地位。這個(gè)最新版本被稱為Big5-2003。
Big5碼是一套雙字節(jié)字符集,使用了雙八碼存儲(chǔ)方法,以兩個(gè)字節(jié)來(lái)安放一個(gè)字。第一個(gè)字節(jié)稱為"高位字節(jié)",第二個(gè)字節(jié)稱為"低位字節(jié)"。"高位字節(jié)"使用了0x81-0xFE,"低位字節(jié)"使用了0x40-0x7E,及0xA1-0xFE。
有關(guān)Big5的更多技術(shù)細(xì)節(jié)讀者可單獨(dú)深入研究,本文就不贅述了。
13、本文小結(jié)
這些字符集和編碼的關(guān)系很容易讓程序員混淆,現(xiàn)在小結(jié)一下。
簡(jiǎn)單來(lái)說(shuō):Unicode、GBK和Big5碼等就是編碼的值(也就是術(shù)語(yǔ)“字符集”),而UTF-8、UTF-16、UTF32之類就是這個(gè)值的表現(xiàn)形式(即術(shù)語(yǔ)“編碼格式”)。
另外:Unicode、GBK和Big5碼等字符集是不兼容的,同一個(gè)漢字在這三個(gè)字符集里的碼值是完全不一樣的。如"漢"的Unicode值與gbk就是不一樣的,假設(shè)Unicode為a040,GBK為b030。以UTF-8為例,UTF-8碼完全只針對(duì)Unicode來(lái)組織的,如果GBK要轉(zhuǎn)UTF-8必須先轉(zhuǎn)Unicode碼,再轉(zhuǎn)UTF-8就OK了。
即GBK、GB2312等與UTF8之間都必須通過(guò)Unicode編碼才能相互轉(zhuǎn)換:
1)GBK、GB2312 --先轉(zhuǎn)--> Unicode --再轉(zhuǎn)--> UTF8
2)UTF8 --先轉(zhuǎn)--> Unicode --再轉(zhuǎn)--> GBK、GB2312
附錄:更多IM技術(shù)精華文章
[1]?新手入門(mén)一篇就夠:從零開(kāi)發(fā)移動(dòng)端IM》
[2]?零*礎(chǔ)IM開(kāi)發(fā)入門(mén)(一):什么是IM系統(tǒng)?》
[3]?零*礎(chǔ)IM開(kāi)發(fā)入門(mén)(二):什么是IM系統(tǒng)的實(shí)時(shí)性?》
[4]?零*礎(chǔ)IM開(kāi)發(fā)入門(mén)(三):什么是IM系統(tǒng)的可靠性?》
[5]?零*礎(chǔ)IM開(kāi)發(fā)入門(mén)(四):什么是IM系統(tǒng)的消息時(shí)序一致性?》
[6]?移動(dòng)端IM開(kāi)發(fā)者必讀(一):通俗易懂,理解移動(dòng)網(wǎng)絡(luò)的“弱”和“慢”》
[7]?移動(dòng)端IM開(kāi)發(fā)者必讀(二):史上最全移動(dòng)弱網(wǎng)絡(luò)優(yōu)化方法總結(jié)》
[8]?從客戶端的角度來(lái)談?wù)勔苿?dòng)端IM的消息可靠性和送達(dá)機(jī)制》
[9]?現(xiàn)代移動(dòng)端網(wǎng)絡(luò)短連接的優(yōu)化手段總結(jié):請(qǐng)求速度、弱網(wǎng)適應(yīng)、安全保障》
[10]?史上最通俗Netty框架入門(mén)長(zhǎng)文:*本介紹、環(huán)境搭建、動(dòng)手實(shí)戰(zhàn)
[11]?強(qiáng)列建議將Protobuf作為你的即時(shí)通訊應(yīng)用數(shù)據(jù)傳輸格式
[12]?IM通訊協(xié)議專題學(xué)習(xí)(一):Protobuf從入門(mén)到精通,一篇就夠!
[13]?微信新一代通信安全解決方案:*于TLS1.3的MMTLS詳解
[14]?探討組合加密算法在IM中的應(yīng)用
[15]?從客戶端的角度來(lái)談?wù)勔苿?dòng)端IM的消息可靠性和送達(dá)機(jī)制
[16]?IM消息送達(dá)保證機(jī)制實(shí)現(xiàn)(一):保證在線實(shí)時(shí)消息的可靠投遞
[17]?理解IM消息“可靠性”和“一致性”問(wèn)題,以及解決方案探討
[18]?融云技術(shù)分享:全面揭秘億級(jí)IM消息的可靠投遞機(jī)制
[19]?IM群聊消息如此復(fù)雜,如何保證不丟不重?
[20]?零*礎(chǔ)IM開(kāi)發(fā)入門(mén)(四):什么是IM系統(tǒng)的消息時(shí)序一致性?
[21]?一套億級(jí)用戶的IM架構(gòu)技術(shù)干貨(下篇):可靠性、有序性、弱網(wǎng)優(yōu)化等
[22]?如何保證IM實(shí)時(shí)消息的“時(shí)序性”與“一致性”?
[23]?阿里IM技術(shù)分享(六):閑魚(yú)億級(jí)IM消息系統(tǒng)的離線推送到達(dá)率優(yōu)化
[24]?微信的海量IM聊天消息序列號(hào)生成實(shí)踐(算法原理篇)
[25]?社交軟件紅包技術(shù)解密(一):全面解密QQ紅包技術(shù)方案——架構(gòu)、技術(shù)實(shí)現(xiàn)等
[26]?網(wǎng)易云信技術(shù)分享:IM中的萬(wàn)人群聊技術(shù)方案實(shí)踐總結(jié)
[27]?企業(yè)微信的IM架構(gòu)設(shè)計(jì)揭秘:消息模型、萬(wàn)人群、已讀回執(zhí)、消息撤回等
[28]?融云IM技術(shù)分享:萬(wàn)人群聊消息投遞方案的思考和實(shí)踐
[29]?為何*于TCP協(xié)議的移動(dòng)端IM仍然需要心跳?;顧C(jī)制?
[30]?一文讀懂即時(shí)通訊應(yīng)用中的網(wǎng)絡(luò)心跳包機(jī)制:作用、原理、實(shí)現(xiàn)思路等
[31]?微信團(tuán)隊(duì)原創(chuàng)分享:Android版微信后臺(tái)保活實(shí)戰(zhàn)分享(網(wǎng)絡(luò)?;钇?
[32]?融云技術(shù)分享:融云安卓端IM產(chǎn)品的網(wǎng)絡(luò)鏈路?;罴夹g(shù)實(shí)踐
[33]?阿里IM技術(shù)分享(九):深度揭密RocketMQ在釘釘IM系統(tǒng)中的應(yīng)用實(shí)踐
[34]?徹底搞懂TCP協(xié)議層的KeepAlive?;顧C(jī)制
[35]?深度解密釘釘即時(shí)消息服務(wù)DTIM的技術(shù)設(shè)計(jì)
[36]?*于實(shí)踐:一套百萬(wàn)消息量小規(guī)模IM系統(tǒng)技術(shù)要點(diǎn)總結(jié)
[37]?跟著源碼學(xué)IM(十):*于Netty,搭建高性能IM集群(含技術(shù)思路+源碼)
[38]?一套十萬(wàn)級(jí)TPS的IM綜合消息系統(tǒng)的架構(gòu)實(shí)踐與思考
(本文已同步發(fā)布于:http://www.52im.net/thread-4433-1-1.html)