各種字符集和編碼詳解

原文在這里:各種字符集和編碼詳解

在軟件的編碼和實(shí)現(xiàn)中,我們可能會碰到個 一個比較頭疼的問題--編碼,不同字符間的編碼和解碼,你確定了解各種字符的編碼嗎?一個朋友問到了我這 個問題,我雖然能回答一兩個出來,但是感覺已經(jīng)有點(diǎn)模糊,混亂了,在網(wǎng)上搜了搜,在書上翻了翻,總結(jié)一下吧。首先按照字符編碼的歷程來看:
1、ASCII
  我們需要了解的最早編碼是ASCII碼。它用7個二進(jìn)制位來表示,由于那個時期生產(chǎn)的大多數(shù)計(jì)算機(jī)使用8位大小的字節(jié),因此用戶不僅可以存放所有 可能的ASCII字符,而且有整整一位空余下來。如果你技藝高超,可以將該位用做自己離奇的目的:WordStar中那個發(fā)暗的燈泡實(shí)際上設(shè)置這個高位, 以指示一個單詞中的最后一個字母,同時這也宣示了WordStar只能用于英語文本。
  由于字節(jié)有多達(dá)8位的空間,因此許多人在想:“呀!我們 可以把128255之間的編碼用做個人的應(yīng)用目的?!眴栴}在于,同時產(chǎn)生這種想法的人相當(dāng)多,而且在128255之間的各個位置上應(yīng)該存放什么這一問 題上,真是仁者見仁智者見智。事實(shí)上,只要人們開始在美國以外的地方購買計(jì)算機(jī),那么各種各樣的不同OEM字符集都會進(jìn)入規(guī)劃設(shè)計(jì)行列,并且各人都會根據(jù) 自己的需要使用高位的128個字符。如此一來,甚至在同語種的文檔之間就不容易實(shí)現(xiàn)互換。 ASCII可被擴(kuò)展,最優(yōu)秀的擴(kuò)展方案是ISO 8859-1,通常稱之為Latin-1。Latin-1包括了足夠的附加字符集來寫基本的西歐語言。
  最后,這個人人參與的OEM終于以ANSI標(biāo)準(zhǔn)的形式形成文件。在ANSI標(biāo)準(zhǔn)中,每個人都認(rèn)同如何使用低端的128個編碼,這與ASCII相當(dāng)一致。不過,根據(jù)所在國籍的不同,處理編碼128以上的字符有許多不同的方式。這些不同的系統(tǒng)稱為代碼頁。
  同時,甚至更為令人頭疼的事情正在逐步上演,亞洲國家的字符表有成千上萬個字符,這樣的字符表是用8位二進(jìn)制無法表示的。該問題的解決通常有賴于稱為DBCS(double byte character set,雙字節(jié)字符集)的繁雜字符系統(tǒng)。
  不過,仍然需要指出一點(diǎn),多數(shù)人還是姑且認(rèn)為一個字節(jié)就是一個字符,以及一個字符就是8個二進(jìn)制位,并且只要確保不將字符串從一臺計(jì)算機(jī)移植到另一臺計(jì) 算機(jī),或者說一種以上的語言,那么這幾乎總是可以湊合。當(dāng)然,只要一進(jìn)入Internet,從一臺計(jì)算機(jī)向另一臺計(jì)算機(jī)移植字符串就成為家常便飯了,而各 種復(fù)雜狀況也隨之呈現(xiàn)出來。令人欣慰的是,Unicode隨即問世了。

作用:表語英語及西歐語言。
位數(shù):ASCII是用7位表示的,能表示128個字符;其擴(kuò)展使用8位表示,表示256個字符。
范圍:ASCII從00到7F,擴(kuò)展從00到FF。

2、ISO8859-1
  屬于單字節(jié)編碼,最多能表示的字符范圍是0-255,應(yīng)用于英文系列。比如,字母'a'的編碼為0x61=97
  很明顯,ISO8859-1編碼表示的字符范圍很窄,無法表示中文字符。但是,由于是單字節(jié)編碼,和計(jì)算機(jī)最基礎(chǔ)的表示單位一致,所以很多時候,仍 舊使用ISO8859-1編碼來表示。而且在很多協(xié)議上,默認(rèn)使用該編碼。比如,雖然"中文"兩個字不存在ISO8859-1編碼,以gb2312編碼為 例,應(yīng)該是"d6d0 cec4"兩個字符,使用ISO8859-1編碼的時候則將它拆開為4個字節(jié)來表示:"d6 d0 ce c4"(事實(shí)上,在進(jìn)行存儲的時候,也是以字節(jié)為單位處理的)。而如果是UTF編碼,則是6個字節(jié)"e4 b8 ad e6 96 87"。很明顯,這種表示方法還需要以另一種編碼為基礎(chǔ)。

作用:擴(kuò)展ASCII,表示西歐、希臘語等。
位數(shù):8位,
范圍:從00到FF,兼容ASCII字符集。

3、GB碼字符集
  全稱是GB2312-80《信息交換用漢字編碼字符集基本集》,1980年發(fā)布,是中文信息處理的國家標(biāo)準(zhǔn),在大陸及海外使用簡體中文的地區(qū)(如新加坡 等)是強(qiáng)制使用的唯一中文編碼。P-Windows3.2和蘋果OS就是以GB2312為基本漢字編碼, Windows 95/98則以GBK為基本漢字編碼、但兼容支持GB2312。

雙字節(jié)編碼
范圍:A1A1~FEFE
A1-A9:符號區(qū),包含682個符號
B0-F7:漢字區(qū),包含6763個漢字

4、GB2312字符集
  GB2312(1980年)一共收錄了7445個字符,包括6763個漢字和682個其它符號。漢字區(qū)的內(nèi)碼范圍高字節(jié)從B0-F7,低字節(jié)從 A1-FE,占用的碼位是72*94=6768。其中有5個空位是D7FA-D7FE。GB2312-80中共收錄了7545個字符,用兩個字節(jié)編碼一個 字符。每個字符最高位為0。GB2312-80編碼簡稱國標(biāo)碼。
  GB2312支持的漢字太少。1995年的漢字?jǐn)U展規(guī)范GBK1.0收錄了21886個符號,它分為漢字區(qū)和圖形符號區(qū)。漢字區(qū)包括21003個字符。

作用:國家簡體中文字符集,兼容ASCII。
位數(shù):使用2個字節(jié)表示,能表示7445個符號,包括6763個漢字,幾乎覆蓋所有高頻率漢字。
范圍:高字節(jié)從A1到F7, 低字節(jié)從A1到FE。將高字節(jié)和低字節(jié)分別加上0XA0即可得到編碼。

5、GB12345-90字符集
  1990年制定了繁體字的編碼標(biāo)準(zhǔn)GB12345-90《信息交換用漢字編碼字符集第一輔助集》,目的在于規(guī)范必須使用繁體字的各種場合,以及古籍整理 等。該標(biāo)準(zhǔn)共收錄6866個漢字(比GB2312多103個字,其它廠商的字庫大多不包括這些字),純繁體的字大概有2200余個。

雙字節(jié)編碼
范圍:A1A1~FEFE
A1-A9:符號區(qū),增加豎排符號
B0-F9:漢字區(qū),包含6866個漢字

6、GBK字符集
  GBK編碼(Chinese Internal Code Specification)是中國大陸制訂的、等同于UCS的新的中文編碼擴(kuò)展國家標(biāo)準(zhǔn)。gbk編碼能夠用來同時表示繁體字和簡體字,而gb2312只 能表示簡體字,gbk是兼容gb2312編碼的。GBK工作小組于1995年10月,同年12月完成GBK規(guī)范。該編碼標(biāo)準(zhǔn)兼容GB2312,共收錄漢字 21003個、符號883個,并提供1894個造字碼位,簡、繁體字融于一庫。Windows95/98簡體中文版的字庫表層編碼就采用的是GBK,通過 GBK與UCS之間一一對應(yīng)的碼表與底層字庫聯(lián)系。

英文名:Chinese Internal Code Specification
中文名:漢字內(nèi)碼擴(kuò)展規(guī)范1.0版
雙字節(jié)編碼,GB2312-80的擴(kuò)充,在碼位上和GB2312-80兼容
范圍:8140~FEFE(剔除xx7F)共23940個碼位
包含21003個漢字,包含了ISO/IEC 10646-1中的全部中日韓漢字
作用:它是GB2312的擴(kuò)展,加入對繁體字的支持,兼容GB2312。
位數(shù):使用2個字節(jié)表示,可表示21886個字符。
范圍:高字節(jié)從81到FE,低字節(jié)從40到FE。

7、BIG5字符集
  是目前臺灣、香港地區(qū)普遍使用的一種繁體漢字的編碼標(biāo)準(zhǔn),包括440個符號,一級漢字5401個、二級漢字7652個,共計(jì)13060個漢字。BIG5又 稱大五碼或五大碼,1984年由臺灣財(cái)團(tuán)法人信息工業(yè)策進(jìn)會和五間軟件公司宏碁 (Acer)、神通 (MiTAC)、佳佳、零壹 (Zero One)、大眾 (FIC)創(chuàng)立,故稱大五碼。Big5碼的產(chǎn)生,是因?yàn)楫?dāng)時臺灣不同廠商各自推出不同的編碼,如倚天碼、IBM PS55、王安碼等,彼此不能兼容;另一方面,臺灣政府當(dāng)時尚未推出官方的漢字編碼,而中國大陸的GB2312編碼亦未有收錄繁體中文字。
  Big5字符集共收錄13,053個中文字,該字符集在中國臺灣使用。耐人尋味的是該字符集重復(fù)地收錄了兩個相同的字:“兀”(0xA461及0xC94A)、“嗀”(0xDCD1及0xDDFC)。
  Big5碼使用了雙字節(jié)儲存方法,以兩個字節(jié)來編碼一個字。第一個字節(jié)稱為“高位字節(jié)”,第二個字節(jié)稱為“低位字節(jié)”。高位字節(jié)的編碼范圍0xA1-0xF9,低位字節(jié)的編碼范圍0x40-0x7E及0xA1-0xFE。
  盡管Big5碼內(nèi)包含一萬多個字符,但是沒有考慮社會上流通的人名、地名用字、方言用字、化學(xué)及生物科等用字,沒有包含日文平假名及片假字母。
  例如臺灣視“著”為“著”的異體字,故沒有收錄“著”字。康熙字典中的一些部首用字(如“亠”、“疒”、“辵”、“癶”等)、常見的人名用字(如“堃”、“煊”、“栢”、“喆”等) 也沒有收錄到Big5之中。

8、GB18030字符集
  GB 18030-2000全稱是《信息技術(shù)信息交換用漢字編碼字符集基本集的擴(kuò)充》,由信息產(chǎn)業(yè)部和原國家質(zhì)量技術(shù)監(jiān)督局于2000年3月17日聯(lián)合發(fā)布,作為國家強(qiáng)制性標(biāo)準(zhǔn)自發(fā)布之日起實(shí)施。
  為了適應(yīng)信息處理技術(shù)快速發(fā)展的需要,1998年10月,由信息產(chǎn)業(yè)部電子四所、北京大學(xué)計(jì)算機(jī)技術(shù)研究所、北大方正集團(tuán)、新天地公司、四通新世紀(jì)公司、 中科院軟件所、長城軟件公司、中軟總公司、金山軟件公司和聯(lián)想公司的技術(shù)人員組成標(biāo)準(zhǔn)起草組。在標(biāo)準(zhǔn)研制過程中,全國信息技術(shù)標(biāo)準(zhǔn)化技術(shù)委員會多次召集標(biāo) 準(zhǔn)起草組和知名公司對標(biāo)準(zhǔn)草案進(jìn)行充分地研究論證,并且特邀了微軟公司、惠普公司、Sun公司和IBM公司等參加,廣泛征求意見。標(biāo)準(zhǔn)起草組經(jīng)過反復(fù)斟酌 和驗(yàn)證,提出了標(biāo)準(zhǔn)制定原則——與GB 2312信息處理交換碼所對應(yīng)的事實(shí)上的內(nèi)碼標(biāo)準(zhǔn)兼容,在字匯上支持GB 13000.1的全部中、日、韓(CJK)統(tǒng)一漢字字符和全部CJK擴(kuò)充A的字符,并且確定了編碼體系和27484個漢字,形成兼容性、擴(kuò)展性、前瞻性兼 備的方案。
  該標(biāo)準(zhǔn)采用單字節(jié)、雙字節(jié)和四字節(jié)三種方式對字符編碼。

作用:它解決了中文、日文、朝鮮語等的編碼,兼容GBK。
位數(shù):它采用變字節(jié)表示(1 ASCII,2,4字節(jié))。可表示27484個文字。
范圍:1字節(jié)從00到7F; 2字節(jié)高字節(jié)從81到FE,低字節(jié)從40到7E和80到FE;4字節(jié)第一三字節(jié)從81到FE,第二四字節(jié)從30到39。

9、通用字符集(UCS)字符集
  ISO/IEC 10646-1 [ISO-10646]定義了一種多于8比特字節(jié)的字符集,稱作通用字符集(UCS),它包含了世界上大多數(shù)可書寫的字符系統(tǒng)。已定義了兩種多8比特字節(jié) 編碼,對每一個字符采用四個8比特字節(jié)編碼的稱為UCS-4,對每一個字符采用兩個8比特字節(jié)編碼的稱為UCS-2。它們僅能夠?qū)CS的前64K字符進(jìn) 行編址,超出此范圍的其它部分當(dāng)前還沒有分配編址。

作用:國際標(biāo)準(zhǔn) ISO 10646 定義了通用字符集 (Universal Character Set)。它是與UNICODE同類的組織,UCS-2和UNICODE兼容。
位數(shù):它有UCS-2和UCS-4兩種格式,分別是2字節(jié)和4字節(jié)。
范圍:目前,UCS-4只是在UCS-2前面加了0x0000。

10、Unicode字符集
  Unicode字符集(簡稱為UCS),國際標(biāo)準(zhǔn)組織于1984年4月成立ISO/IEC JTC1/SC2/WG2工作組,針對各國文字、符號進(jìn)行統(tǒng)一性編碼。1991年美國跨國公司成立Unicode Consortium,并于1991年10月與WG2達(dá)成協(xié)議,采用同一編碼字集。目前Unicode是采用16位編碼體系,其字符集內(nèi)容與 ISO10646的BMP(Basic Multilingual Plane)相同。Unicode于1992年6月通過DIS(Draf International Standard),目前版本V2.0于1996公布,內(nèi)容包含符號6811個,漢字20902個,韓文拼音11172個,造字區(qū)6400個,保留 20249個,共計(jì)65534個。Unicode編碼后的大小是一樣的.例如一個英文字母 "a" 和 一個漢字 "好",編碼后都是占用的空間大小是一樣的,都是兩個字節(jié)!
  Unicode可以用來表示所有語言的字符,而且是定長雙字節(jié)(也有四字節(jié)的)編碼,包括英文字母在內(nèi)。所以可以說它是不兼容ISO8859-1編碼的, 也不兼容任何編碼。不過,相對于ISO8859-1編碼來說,uniocode編碼只是在前面增加了一個0字節(jié),比如字母'a'為"00 61"。
  需要說明的是,定長編碼便于計(jì)算機(jī)處理(注意GB2312/GBK不是定長編碼),而unicode又可以用來表示所有字符,所以在很多軟件內(nèi)部是使用unicode編碼來處理的,比如java。
  UNICODE字符集有多個編碼方式,分別是UTF-8,UTF-16,UTF-32和UTF-7編碼。

UTF-8
  UTF:UCS Transformation Format.考慮到unicode編碼不兼容ISO8859-1編碼,而且容易占用更多的空間:因?yàn)閷τ谟⑽淖帜?,unicode也需要兩個字節(jié)來表 示。所以unicode不便于傳輸和存儲。因此而產(chǎn)生了utf編碼,utf編碼兼容ISO8859-1編碼,同時也可以用來表示所有語言的字符,不 過,utf編碼是不定長編碼,每一個字符的長度從1-6個字節(jié)不等。另外,utf編碼自帶簡單的校驗(yàn)功能。一般來講,英文字母都是用一個字節(jié)表示,而漢字 使用三個字節(jié)。
  注意,雖然說utf是為了使用更少的空間而使用的,但那只是相對于unicode編碼來說,如果已經(jīng)知道是漢字,則使用GB2312/GBK無疑是 最節(jié)省的。不過另一方面,值得說明的是,雖然utf編碼對漢字使用3個字節(jié),但即使對于漢字網(wǎng)頁,utf編碼也會比unicode編碼節(jié)省,因?yàn)榫W(wǎng)頁中包 含了很多的英文字符。
  UTF8編碼后的大小是不一定,例如一個英文字母"a" 和 一個漢字 "好",編碼后占用的空間大小就不樣了,前者是一個字節(jié),后者是三個字節(jié)!編碼的方法是從低位到高位。黃色為標(biāo)志位其它著色為了顯示其,編碼后的位置。

UTF-16
  采用2 字節(jié),Unicode中不同部分的字符都同樣基于現(xiàn)有的標(biāo)準(zhǔn)。這是為了便于轉(zhuǎn)換。從 0x0000到0x007F是ASCII字符,從0x0080到0x00FF是ISO-8859-1對ASCII的擴(kuò)展。希臘字母表使用從0x0370到 0x03FF 的代碼,斯拉夫語使用從0x0400到0x04FF的代碼,美國使用從0x0530到0x058F的代碼,希伯來語使用從0x0590到0x05FF的代 碼。中國、日本和韓國的象形文字(總稱為CJK)占用了從0x3000到0x9FFF的代碼;
  由于0x00在c語言及操作系統(tǒng)文件名等中有特殊意義,故很多情況下需要UTF-8編碼保存文本,去掉這個0x00。舉例如下:

UTF-16: 0x0080 = 0000 0000 1000 0000
UTF-8: 0xC280 = 1100 0010 1000 0000

UTF-32
采用4字節(jié)。

UTF-7
  A Mail-Safe Transformation Format of Unicode(RFC1642)。這是一種使用 7 位 ASCII 碼對 Unicode 碼進(jìn)行轉(zhuǎn)換的編碼。它的設(shè)計(jì)目的仍然是為了在只能傳遞 7 為編碼的郵件網(wǎng)關(guān)中傳遞信息。 UTF-7 對英語字母、數(shù)字和常見符號直接顯示,而對其他符號用修正的 Base64 編碼。符號 + 和 - 號控制編碼過程的開始和暫停。所以亂碼中如果夾有英文單詞,并且相伴有 + 號和 - 號,這就有可能是 UTF-7 編碼。

作用:為世界650種語言進(jìn)行統(tǒng)一編碼,兼容ISO-8859-1。
位數(shù):UNICODE字符集有多個編碼方式,分別是UTF-8,UTF-16和UTF-32。

很多人以為UTF-8等和Unicode都是字符集或都是編碼方式,其實(shí)這是誤區(qū)。

到以上為止,大部分常用的字符集已經(jīng)基本列舉完畢,再看一些其他的編碼方式:

MIME 編碼
  MIME 是“多用途網(wǎng)際郵件擴(kuò)充協(xié)議”的縮寫,在 MIME 協(xié)議之前,郵件的編碼曾經(jīng)有過 UUENCODE 等編碼方式 ,但是由于 MIME 協(xié)議算法簡單,并且易于擴(kuò)展,現(xiàn)在已經(jīng)成為郵件編碼方式的主流,不僅是用來傳輸 8 bit 的字符,也可以用來傳送二進(jìn)制的文件 ,如郵件附件中的圖像、音頻等信息,而且擴(kuò)展了很多基于MIME 的應(yīng)用。從編碼方式來說,MIME 定義了兩種編碼方法Base64與QP(Quote-Printable)

Base64
  按照RFC2045的定義,Base64被定義為:Base64內(nèi)容傳送編碼被設(shè)計(jì)用來把任意序列的8位字節(jié)描述為一種不易被人直接識別的形式。
  為什么要使用Base64?
在設(shè)計(jì)這個編碼的時候,我想設(shè)計(jì)人員最主要考慮了3個問題:
1.是否加密?
2.加密算法復(fù)雜程度和效率
3.如何處理傳輸?
  加密是肯定的,但是加密的目的不是讓用戶發(fā)送非常安全的Email。這種加密方式主要就是“防君子不防小人”。即達(dá)到一眼望去完全看不出內(nèi)容即可。 基 于這個目的加密算法的復(fù)雜程度和效率也就不能太大和太低。和上一個理由類似,MIME協(xié)議等用于發(fā)送Email的協(xié)議解決的是如何收發(fā)Email,而并不 是如何安全的收發(fā)Email。因此算法的復(fù)雜程度要小,效率要高,否則因?yàn)榘l(fā)送Email而大量占用資源,路就有點(diǎn)走歪了。
  但是,如果是基于以上兩點(diǎn),那么我們使用最簡單的愷撒法即可,為什么Base64看起來要比愷撒法復(fù)雜呢?這是因?yàn)樵贓mail的傳送過程中,由于歷史原 因,Email只被允許傳送ASCII字符,即一個8位字節(jié)的低7位。因此,如果您發(fā)送了一封帶有非ASCII字符(即字節(jié)的最高位是1)的Email通 過有“歷史問題”的網(wǎng)關(guān)時就可能會出現(xiàn)問題。網(wǎng)關(guān)可能會把最高位置為0!很明顯,問題就這樣產(chǎn)生了!因此,為了能夠正常的傳送Email,這個問題就必須 考慮!所以,單單靠改變字母的位置的愷撒之類的方案也就不行了。關(guān)于這一點(diǎn)可以參考RFC2046。
基于以上的一些主要原因產(chǎn)生了Base64編碼。
  Base64編碼要求把3個8位字節(jié)(3*8=24)轉(zhuǎn)化為4個6位的字節(jié)(4*6=24),之后在6位的前面補(bǔ)兩個0,形成8位一個字節(jié)的形式。

QP(Quote-Printable)
  通??s寫為“Q”方法,其原理是把一個 8 bit 的字符用兩個16進(jìn)制數(shù)值表示,然后在前面加“=”。所以我們看到經(jīng)過QP編碼后的文件通常是這個樣子:

=B3=C2=BF=A1=C7=E5=A3=AC=C4=FA=BA=C3=A3=A1

最后,我們希望你看了這篇文章之后不要混淆字符集和字符編碼的概念,還有對以上談到的各種編碼方式的原因有大致的了解,象utf-8這類是為了解析 unicode這種字符集而制定,而base64這類是為了解決實(shí)際的網(wǎng)絡(luò)應(yīng)用而制定。為了讓你便于記憶,對先前介紹的字符集進(jìn)行統(tǒng)計(jì)和分類:

語言 字符集 正式名稱
英語、西歐語 ASCII,ISO-8859-1 MBCS 多字節(jié)
簡體中文 GB2312 MBCS 多字節(jié)
繁體中文 BIG5 MBCS 多字節(jié)
簡繁中文 GBK MBCS 多字節(jié)
中文、日文及朝鮮語 GB18030 MBCS 多字節(jié)
各國語言 UNICODE,UCS DBCS 寬字節(jié)

分類: 基礎(chǔ)知識

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容