字符集與字符編碼(理解ASCII、ANSI、UTF-8、Unicode,解決各種亂碼問(wèn)題)
相信很多同學(xué)也像我一樣,經(jīng)常在工作和學(xué)習(xí)中遇到字符編碼的疑惑或者受到亂碼的困擾,每次遇到問(wèn)題都需要去學(xué)習(xí)了解不同的名詞含義甚至需要深入學(xué)習(xí)不同的編碼機(jī)制,不勝煩惱,所以今天我將自己的學(xué)習(xí)心得記錄下來(lái),希望能簡(jiǎn)單明了地描述字符集和字符編碼。
1 多種字符集與多種編碼共存的原因
- 首先必須要認(rèn)識(shí)到一點(diǎn),不論是簡(jiǎn)單的字符還是更復(fù)雜的圖像、聲音、視頻等都是用于描述現(xiàn)實(shí)世界的信息,只是信息的表現(xiàn)形式不同,可以理解為對(duì)現(xiàn)實(shí)世界抽象的結(jié)果。例如,遠(yuǎn)古時(shí)期的象形文字最初就像是將客觀事物的外觀畫(huà)出來(lái)用于描述該客觀事物,隨著人類對(duì)世界的認(rèn)知越來(lái)越深入,象形文字在信息傳遞過(guò)程中顯得極為不便,于是文字就向著更為抽象且簡(jiǎn)單化、符合人類認(rèn)知習(xí)慣的方向發(fā)展和轉(zhuǎn)變,在這個(gè)過(guò)程中因?yàn)楦鱾€(gè)不同地區(qū)的人對(duì)世界的理解和認(rèn)識(shí)不同,所以會(huì)形成不同體系的語(yǔ)言和文字,如中國(guó)使用漢語(yǔ)體系、日本使用日語(yǔ)體系、英美使用英語(yǔ)體系,這是造成多種字符集共存的歷史和根源原因,這是一個(gè)無(wú)可避免的客觀歷史問(wèn)題。
- 每一種不同的語(yǔ)言體系都有嚴(yán)格的標(biāo)準(zhǔn)和約定來(lái)保證語(yǔ)言的規(guī)范性,這樣在不同的人使用文字進(jìn)行溝通時(shí),只要遵循相同的標(biāo)準(zhǔn)和約定就可以有效地實(shí)現(xiàn)信息傳遞。就像小時(shí)候?qū)W語(yǔ)文時(shí)常用的新華字典,其實(shí)就是國(guó)家為了規(guī)范人民在文字、發(fā)音、含義上的共識(shí)而采取的有效教育決策。但是新華字典只規(guī)范了中國(guó)的漢語(yǔ)言體系,并未制定其他國(guó)家語(yǔ)言體系的標(biāo)準(zhǔn)(因?yàn)檫@是別人國(guó)家的事情),于是不同的國(guó)家就制定了自己國(guó)家語(yǔ)言體系的文字規(guī)范與標(biāo)準(zhǔn)。如美國(guó)最早制定了ASCII字符集,包含了英文字符、數(shù)字字符、常用的圖形字符及控制字符,中國(guó)制定了GB2312字符集,包含了ASCII字符集以及常用的漢字字符,日本制定了Shift_JIS字符集,包含了全形及半形拉丁字母、平假名、片假名、符號(hào)及日語(yǔ)漢字。
- 為了能夠在計(jì)算機(jī)中表示和處理字符信息,就必須對(duì)每個(gè)字符進(jìn)行編碼,實(shí)現(xiàn)字符到二進(jìn)制之間的一一映射,通常這個(gè)映射需要分兩個(gè)步驟來(lái)完成:第一步,給字符集中的每一個(gè)字符都賦予一個(gè)獨(dú)一無(wú)二的數(shù)值編號(hào),將字符映射為數(shù)值,如漢字使用區(qū)位碼;第二步,通過(guò)一定的機(jī)制將數(shù)值編號(hào)映射為二進(jìn)制形式,將數(shù)值映射為特定形式的二進(jìn)制編碼。以上整個(gè)過(guò)程就稱為字符集編碼,字符集和字符集編碼雖然是配套使用,但字符集僅僅相當(dāng)于字符的容器,是概念上的容納,如果想要在計(jì)算機(jī)中使用字符集中的字符則必要要進(jìn)一步對(duì)字符集中的每個(gè)字符進(jìn)行編碼,映射成為特定的二進(jìn)制形式。
2 字符集
2.1 ASCII字符集
2.1.1 標(biāo)準(zhǔn)ASCII字符集
- ASCII (American Standard Code for Information Interchange):美國(guó)信息交換標(biāo)準(zhǔn)代碼是基于拉丁字母的一套電腦編碼系統(tǒng),主要用于顯示現(xiàn)代英語(yǔ)和其他西歐語(yǔ)言。它是最通用的信息交換標(biāo)準(zhǔn),并等同于國(guó)際標(biāo)準(zhǔn) ISO/IEC 646。ASCII第一次以規(guī)范標(biāo)準(zhǔn)的類型發(fā)表是在1967年,最后一次更新則是在1986年,到目前為止共定義了128個(gè)字符 。
- 在英語(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)。
- 但是,這里又出現(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的這一段。
2.1.2 ANSI
- 為使計(jì)算機(jī)支持更多語(yǔ)言,通常使用 0x00–0x7F范圍的1 個(gè)字節(jié)來(lái)表示 1個(gè)英文字符,超出此范圍的使用0x80–0xFFFF來(lái)編碼,即擴(kuò)展的ASCII編碼。不同的國(guó)家和地區(qū)制定了不同的標(biāo)準(zhǔn),由此產(chǎn)生了GB2312、GBK、GB18030、Big5、Shift_JIS等各自的編碼標(biāo)準(zhǔn),這些使用多個(gè)字節(jié)來(lái)代表一個(gè)字符的各種漢字延伸編碼方式,稱為 ANSI 編碼,美國(guó)國(guó)家標(biāo)準(zhǔn)學(xué)會(huì)(AMERICAN NATIONAL STANDARDS INSTITUTE: ANSI)。在簡(jiǎn)體中文Windows操作系統(tǒng)中,ANSI 編碼代表GB2312編碼;在繁體中文Windows操作系統(tǒng)中,ANSI編碼代表Big5;在日文Windows操作系統(tǒng)中,ANSI 編碼代表 JIS編碼。
- 可以理解為ANSI是使用一個(gè)字節(jié)來(lái)表示標(biāo)準(zhǔn)ASCII字符集,使用兩個(gè)或者更多字節(jié)來(lái)表示本地字符集,其中地方語(yǔ)言字符集在不同國(guó)家有不同含義,通常與國(guó)家制定的字符集標(biāo)準(zhǔn)兼容,例如我國(guó)的簡(jiǎn)體中文字符集GB2312。
0x00–0x7F | 0x80–0xFFFF |
---|---|
ASCII字符集 | 地方語(yǔ)言字符集 |
2.2 漢字字符集
2.2.1 GB2312
- GB2312或GB2312-80是一個(gè)簡(jiǎn)體中文字符集的中國(guó)國(guó)家標(biāo)準(zhǔn),全稱為《信息交換用漢字編碼字符集–基本集》,由中國(guó)國(guó)家標(biāo)準(zhǔn)總局發(fā)布,1981年5月1日實(shí)施。GB2312編碼通行于大陸;新加坡等地也采用此編碼。幾乎所有的中文系統(tǒng)和國(guó)際化的軟件都支持GB2312。
- GB2312標(biāo)準(zhǔn)共收錄6763個(gè)漢字,其中一級(jí)漢字3755個(gè),二級(jí)漢字3008個(gè);同時(shí),GB2312收錄了包括拉丁字母、希臘字母、日文平假名及片假名字母、俄羅斯語(yǔ)西里爾字母在內(nèi)的682個(gè)全形字符。
2.2.2 GBK
- GB2312的出現(xiàn),基本滿足了漢字的計(jì)算機(jī)處理需要,它所收錄的漢字已經(jīng)覆蓋99.75%的使用頻率。但對(duì)于人名、古漢語(yǔ)等方面出現(xiàn)的罕用字,GB2312不能處理,這導(dǎo)致了GB2312的擴(kuò)展版字符集GBK及GB18030漢字字符集的出現(xiàn)。
- GBK全稱《漢字內(nèi)碼擴(kuò)展規(guī)范》,發(fā)布于1995年,只是 “技術(shù)規(guī)范指導(dǎo)性文件”,并不屬于國(guó)家標(biāo)準(zhǔn)。其中的K是漢語(yǔ)拼音 Kuo Zhan(擴(kuò)展)中的“Kuo”的首字母,意思是GB2312的擴(kuò)展版,在GB2312的基礎(chǔ)上將字符擴(kuò)展到兩萬(wàn)多個(gè),完全兼容 GB2312。
2.2.3 GB18030
- GB18030,全稱《信息技術(shù)中文編碼字符集》,是中華人民共和國(guó)國(guó)家標(biāo)準(zhǔn)所規(guī)定的變長(zhǎng)多字節(jié)字符集,其對(duì)GB2312-1980完全向后兼容,與GBK基本向后兼容,并支持Unicode(GB 13000)的所有碼位,GB18030-2005共收錄漢字70,244個(gè)。
- 2022年7月19日,國(guó)家市場(chǎng)監(jiān)督管理總局(國(guó)家標(biāo)準(zhǔn)化管理委員會(huì))批準(zhǔn)《信息技術(shù) 中文編碼字符集》強(qiáng)制性國(guó)家標(biāo)準(zhǔn)GB 18030-2022,2023年8月1日實(shí)施。
- 總結(jié)一下就是,GB2312、GBK和GB18030都是包含了標(biāo)準(zhǔn)ASCII字符集和漢字字符集的中國(guó)標(biāo)準(zhǔn)字符集,區(qū)別是從GB2312到GB18030其容納的字符數(shù)量越來(lái)越豐富,但又都是向前兼容的,其關(guān)系可以用下圖來(lái)描述。
2.3 Unicode字符集
不同的地區(qū)和國(guó)家使用不同的字符編碼,使得不同國(guó)家之間使用計(jì)算機(jī)進(jìn)行交流變得很困難,經(jīng)常會(huì)出現(xiàn)亂碼的問(wèn)題,比如:對(duì)于同一個(gè)二進(jìn)制數(shù)據(jù),不同的編碼會(huì)解析出不同的字符。例如,\xD6D0使用GB2312字符集解析時(shí)對(duì)應(yīng)漢字“中”,但使用SHIFT_JIS解析時(shí)對(duì)應(yīng)日文“??”,可以使用在線轉(zhuǎn)碼工具進(jìn)行驗(yàn)證。于是,使用一種統(tǒng)一的規(guī)則對(duì)全世界所有國(guó)家和地區(qū)的字符進(jìn)行統(tǒng)一編碼成為了互聯(lián)網(wǎng)發(fā)展過(guò)程中亟需解決的重要問(wèn)題。
Unicode,中文又稱萬(wàn)國(guó)碼、國(guó)際碼、統(tǒng)一碼、單一碼,它為每種語(yǔ)言中的每個(gè)字符設(shè)定了統(tǒng)一而且唯一的二進(jìn)制編碼,以滿足跨語(yǔ)言、跨平臺(tái)進(jìn)行文本轉(zhuǎn)換、處理的要求。在Unicode環(huán)境下,不會(huì)再有語(yǔ)言的編碼沖突,在同屏下,可以顯示任何語(yǔ)言的內(nèi)容,Unicode是圍繞全球通用字符集(Universal Character Set,UCS)的標(biāo)準(zhǔn)來(lái)發(fā)展的,當(dāng)前使用兩個(gè)字節(jié)來(lái)編碼,稱為UCS-2,若后期出現(xiàn)字符增加兩個(gè)字節(jié)不夠用時(shí)則使用4個(gè)字節(jié)來(lái)編碼,稱為UCS-4。
3 字符編碼
每一種字符集都必須配套有特定的編碼規(guī)則,將字符的編號(hào)映射成為二進(jìn)制編碼,從而實(shí)現(xiàn)計(jì)算機(jī)中的表示、存儲(chǔ)和計(jì)算。
3.1 ASCII字符集的編碼
使用7位二進(jìn)制來(lái)表示一個(gè)ASCII字符,共計(jì)表示128個(gè)字符,包含了大小寫(xiě)英文字母、數(shù)字、可視字符以及若干控制字符,其編碼的取值范圍為0x00–0x7F。
3.2 GB系列字符集的編碼
ASCII字符集部分使用0x00–0x7F表示,與ASCII編碼兼容,漢字部分使用區(qū)位碼+0xA0A0表示,使?jié)h字編碼與ASCII編碼不出現(xiàn)重疊。
3.3 Unicode字符集的編碼
- 雖然GB系列字符集采用區(qū)位碼來(lái)表示漢字的編號(hào),但Unicode采用了完全不同的方式,Unicode中每個(gè)漢字的編號(hào)與GB字符集中的編號(hào)完全不同,他給每個(gè)漢字定義了一個(gè)獨(dú)一無(wú)二的Unicode編號(hào)。
- 例如,漢字“中”的在GB系列字符集中被映射到區(qū)碼為54(0x36),位碼為48(0x30)的位置上,所以其區(qū)位碼為0x3630,加上0xA0A0得到最終編碼0xD6D0;而在Unicode字符集中,“中”字被映射到編號(hào)0x4E2D位置上,其編碼方式有UTF-8、UTF-16和UTF-32三種,對(duì)0x4E2D編碼后的結(jié)果均不相同。
- UTF-8(8位元,Universal Character Set/Unicode Transformation Format)是針對(duì)Unicode的一種可變長(zhǎng)度字符編碼,分成單字節(jié)、雙字節(jié)、三字節(jié)、四字節(jié)模式,理論上可以最多到4個(gè)字節(jié)長(zhǎng),然而16位BMP字符最多只用到3字節(jié)長(zhǎng),Bigendian UCS-4字節(jié)串的排列順序是預(yù)定的,字節(jié)0xFE和0xFF在UTF-8編碼中從未用到。
UTF-8 的編碼規(guī)則:
(1)對(duì)于單字節(jié)的符號(hào),字節(jié)的第一位設(shè)為 0,后面 7 位為這個(gè)符號(hào)的 Unicode 碼。因此對(duì)于英語(yǔ)字母,UTF-8 編碼和 ASCII 碼是相同的, 所以 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 碼。 - 例如:英文字符’a’對(duì)應(yīng)的Unicode字符集編號(hào)為0x61,屬于0x00–0x7F之間,所以采用單字節(jié)編碼,0110 0001。漢字字符“中”對(duì)應(yīng)的Unicode字符集編號(hào)為0x4E2D,處于0x800–0xFFFF之間,所以需要采用三字節(jié)編碼,依據(jù)規(guī)則(2)n=3,第一個(gè)字節(jié)的前3位都設(shè)為1,第4位設(shè)為0,所以第一個(gè)字節(jié)為 1110 xxxx,后面還有兩個(gè)字節(jié)均以10開(kāi)頭,所以都為 10xx xxxx,最終的形式為(字節(jié)從高到低): 1110 xxxx
10xx xxxx 10xx xxxx,將 4E2D 的二進(jìn)制形式 0100 1110 0010 1101 從左到右依次填充編碼中的 x 即可得到最終的編碼結(jié)果: 1110 0100 1011 1000 1010 1101,即 0xE4 0xB8 0xAD。 - UTF-16 也是一種變長(zhǎng)字符編碼, 這種編碼方式比較特殊, 它將字符編碼成 2 字節(jié) 或者 4 字節(jié)。
UTF-16 的編碼規(guī)則:
(1)對(duì)于Unicode編號(hào)小于 0x10000的字符,使用2字節(jié)存儲(chǔ),不進(jìn)行任何轉(zhuǎn)換,直接存儲(chǔ)Unicode編號(hào),如漢字“中”的Unicode編號(hào)為0x4E2D,則其編碼就為 0x4E2D,但多字節(jié)數(shù)值存在字節(jié)序問(wèn)題,默認(rèn)使用小端存儲(chǔ),其存儲(chǔ)順序?yàn)椋?x2D 0x4E。如英文字符“a”的Unicode編號(hào)為 0x0061,則其存儲(chǔ)順序?yàn)椋?x61 0x00。
(2)對(duì)于Unicode編號(hào)在0x10000–0x10FFFF之間的字符,使用4字節(jié)存儲(chǔ),前兩個(gè)字節(jié)的高6位固定為110110,后兩個(gè)字節(jié)的高6位固定為110111,前后部分各剩余10位二進(jìn)制表示符號(hào)的Unicode編號(hào)減去 0x10000 的結(jié)果。
例如:線性標(biāo)志符號(hào)的Unicode編號(hào)為 U+10600,減去 0x10000后得 0x 00600,0000 0000 0110 0000 0000,按照(2)中的規(guī)則,共計(jì)4個(gè)字節(jié),其形式為110110xx xxxxxxxx 110111xx xxxxxxxx,使用0x00600的二進(jìn)制填充形式中的x即可得到
11011000 00000001 11011110 00000000,即 0xD8 0x01 0xDE 0x00。
(3)Unicode編號(hào)大于 0x10FFFF的字符無(wú)法使用 UTF-16編碼表示。
UTF-32的編碼規(guī)則: - UTF-32采用固定4個(gè)字節(jié)長(zhǎng)度的編碼,足以容納Unicode中的所有字符,無(wú)須任何轉(zhuǎn)換,直接存儲(chǔ)Unicode編號(hào)即可。
4 Editplus編碼案例
Editplus文本編輯器支持各種編碼格式,這里僅對(duì)簡(jiǎn)體中文用戶經(jīng)常遇到的字符編碼情況進(jìn)行驗(yàn)證。
4.1 英文字符編碼
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-777797.html
4.2 簡(jiǎn)體中文字符編碼
參考:
[1] https://zhuanlan.zhihu.com/p/427488961
[2] https://blog.csdn.net/Deft_MKJing/article/details/79460485
[3] https://blog.csdn.net/Deft_MKJing/article/details/79460485
[4] https://www.toolhelper.cn/EncodeDecode/EncodeDecode文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-777797.html
到了這里,關(guān)于字符集與字符編碼(理解ASCII、ANSI、UTF-8、Unicode,解決各種亂碼問(wèn)題)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!