计算机编码总结
英文字母:
字節(jié)數(shù) : 1;編碼:GB2312
字節(jié)數(shù) : 1;編碼:GBK
字節(jié)數(shù) : 1;編碼:GB18030
字節(jié)數(shù) : 1;編碼:ISO-8859-1
字節(jié)數(shù) : 1;編碼:UTF-8
字節(jié)數(shù) : 4;編碼:UTF-16
字節(jié)數(shù) : 2;編碼:UTF-16BE
字節(jié)數(shù) : 2;編碼:UTF-16LE
?
中文漢字:
字節(jié)數(shù) : 2;編碼:GBK
字節(jié)數(shù) : 2;編碼:GB18030
字節(jié)數(shù) : 1;編碼:ISO-8859-1
字節(jié)數(shù) : 3;編碼:UTF-8
字節(jié)數(shù) : 4;編碼:UTF-16
字節(jié)數(shù) : 2;編碼:UTF-16BE
字節(jié)數(shù) : 2;編碼:UTF-16LE
?
編碼發(fā)展歷史簡(jiǎn)介
第一階段 ASCII
在計(jì)算機(jī)中,所有的數(shù)據(jù)只可能是0或者1(用高電平和低電平分別表示1和0),那么我們通??吹降淖址簿椭荒苡?和1來表示呀。于是科學(xué)家們(這里指的是美國(guó)的科學(xué)家)就想出一個(gè)辦法,把一個(gè)特定的數(shù)字對(duì)應(yīng)一個(gè)特定的字母進(jìn)行存儲(chǔ)和傳輸,比如我需要存儲(chǔ)字母a,那么我存入一個(gè)數(shù)字97(即在計(jì)算機(jī)中存入二進(jìn)制(01100001),這個(gè)過程叫做編碼(encode),而我們?cè)谧x取數(shù)據(jù)的時(shí)候,當(dāng)遇到97時(shí),我們就讓計(jì)算機(jī)顯示字母a,這個(gè)過程叫做解碼(decode)。
為了大家在數(shù)據(jù)傳輸?shù)臅r(shí)候不至于產(chǎn)生誤會(huì),那么我們需要讓所有的人都使用數(shù)字97來代表字母a,所以需要制定一份標(biāo)準(zhǔn)(即碼表),最開始的這個(gè)標(biāo)準(zhǔn)叫做ASCII碼表。
規(guī)則
- 所有的控制字符(比如CR回車、DEL刪除等)編碼在0-31范圍以及127中。
- 把所有的標(biāo)點(diǎn)符號(hào),英文大小寫全部放在32-126范圍中。
- 防止以后出現(xiàn)需要補(bǔ)充的情況,把128-255位這么多位置留出來,應(yīng)該足夠用了吧!所以設(shè)置一個(gè)字節(jié)8位二進(jìn)制,把這個(gè)標(biāo)準(zhǔn)叫American Standard Code for Information Interchange(美國(guó)標(biāo)準(zhǔn)信息交換代碼,簡(jiǎn)寫為ASCII),標(biāo)準(zhǔn)制定結(jié)束。
等等,我們的中文字呢?
美國(guó)的"磚家"沒有考慮那么久遠(yuǎn)呢!這就是后面出現(xiàn)那么多問題的根源所在啊。
實(shí)現(xiàn)方式
第一位始終未0,后面7位表示0-127的范圍,一個(gè)數(shù)字對(duì)應(yīng)一個(gè)字母或者標(biāo)點(diǎn)符號(hào),亦或者控制符號(hào),即所有的ASCII碼的統(tǒng)一形式為0xxxx xxxx。
第二階段 GB2312,GBK, BIG5 Latin1, ISO-8859-1, JIS, ANSI...
計(jì)算機(jī)技術(shù)到了歐洲,歐洲人發(fā)現(xiàn)怎么我們的那么多符號(hào)沒有編進(jìn)去啊!
所以歐洲"磚家"坐到了一起,開始討論。
發(fā)現(xiàn)既然美國(guó)人把第一位流出來了,那么我們就用128-255的位置好了。
規(guī)則
128-159之間為控制字符,160-255位文字符號(hào),其中包括了西歐語言、希臘語、泰語、阿拉伯語、希伯來語。
剛好把美國(guó)人給的空間全部用完,世界真美好,謝謝美利堅(jiān)預(yù)留的每一個(gè)位置。
磚家們決定把他們的編碼名稱叫做Latin1,后面由于歐洲統(tǒng)一制定ISO標(biāo)準(zhǔn),所以又有了一個(gè)ISO的名稱,即ISO-8859-1。
實(shí)現(xiàn)方式
- 0-127的所有位置不動(dòng),那么可以兼容ASCII,二進(jìn)制位0xxx xxxx
- 128-255位置全部用完,二進(jìn)制位1xxx xxxx
由于所有的位置全部用完,而歐元符號(hào)實(shí)在指定標(biāo)準(zhǔn)之后才出現(xiàn)的,所以在這個(gè)碼表中連歐洲人自己的貨幣符號(hào)都沒有辦法放進(jìn)去。
計(jì)算機(jī)技術(shù)當(dāng)然也傳到了亞洲大地,比如中國(guó)。
中國(guó)磚家們坐在一起發(fā)現(xiàn),美國(guó)人搞的這個(gè)東西真的有問題,預(yù)留才128-255的空間,可是我們的漢字個(gè)數(shù)遠(yuǎn)遠(yuǎn)超出了這個(gè)數(shù)目啊,怎么辦??
后面聰明的中國(guó)磚家們發(fā)現(xiàn),只能使用2個(gè)字節(jié)了,否則真的搞不定。
由于必須和美國(guó)原來制定的ASCII不沖突,所以指定了如下規(guī)則
規(guī)則
- 如果一個(gè)字節(jié)中第一位為0,那么這就是一個(gè)ASCII字符。
- 如果一個(gè)字節(jié)中第一位為1,那么這個(gè)是漢字,認(rèn)定需要2個(gè)字節(jié)才表示一個(gè)編碼的文字。
把這個(gè)碼表叫GB2312
這個(gè)碼表中包含漢字6763個(gè)和非漢字圖形字符682個(gè)。
還有很多的空間沒有用到,索性全部預(yù)留了吧。
實(shí)現(xiàn)方式 - 0xxxxxxx:表示為ASCII字符
-1xxxxxxx 1xxxxxxx:表示為漢字
后來,中國(guó)磚家們發(fā)現(xiàn),很多的不常用漢字沒有在碼表中,于是添加了很多的漢字進(jìn)去,這個(gè)編碼叫做GBK,實(shí)現(xiàn)方式和GB2312是完全一樣的,兼容GB2312,當(dāng)然也兼容ASCII。
實(shí)現(xiàn)方式
- 0xxxxxxx:表示為ASCII字符
-1xxxxxxx xxxxxxxx:表示為漢字
后面再次添加更多的字符進(jìn)去,再次命名為GB18030,兼容GBK。由于漢字很多,2個(gè)字節(jié)并不能完全包括進(jìn)去,所以GB18030采用2\4位混編的形式。
當(dāng)然計(jì)算機(jī)也傳到了日本(JIS)、韓國(guó)、臺(tái)灣(BIG5)等等地方,大家全部發(fā)揮自己的聰明才智,各自實(shí)現(xiàn)了自己的編碼。這些編碼都與ASCII兼容,但是相互之間不兼容。
使用 2 個(gè)字節(jié)來代表一個(gè)字符的各種漢字延伸編碼方式,稱為 ANSI 編碼,又稱為"MBCS(Muilti-Bytes Charecter Set,多字節(jié)字符集)"。在簡(jiǎn)體中文系統(tǒng)下,ANSI 編碼代表 GB2312 編碼,在日文操作系統(tǒng)下,ANSI 編碼代表 JIS 編碼,所以在中文 windows下要轉(zhuǎn)碼成gb2312,gbk只需要把文本保存為ANSI編碼即可。 不同ANSI編碼之間互不兼容
第三階段
隨著通訊越來越多,而老美發(fā)現(xiàn)在自己公司需要國(guó)際化的時(shí)候,自己原來埋的這個(gè)雷真的害了自己。
于是乎,開始研討把世界上幾乎所有文字全部放在一個(gè)碼表中,而這個(gè)包羅萬象的碼表就叫做Unicode,即萬國(guó)碼。
Unicode是國(guó)際組織制定的可以容納世界上所有文字和符號(hào)的字符編碼方案。Unicode用數(shù)字0-0x10FFFF來映射這些字符,最多可以容納1114112個(gè)字符,或者說有1114112個(gè)碼位。碼位就是可以分配給字符的數(shù)字。
實(shí)際上,在軟件制造商的協(xié)會(huì)(unicode.org)在做這個(gè)工作時(shí),國(guó)際標(biāo)準(zhǔn)化組織(ISO)在做同樣的事情,最后大家都意識(shí)到世界上并不需要兩個(gè)不同的萬國(guó)碼,于是大家坐在一起合并研究的成果,最后的結(jié)果就是現(xiàn)在的Unicode。
各個(gè)編碼及其范圍
ASCII
編碼范圍00-7F,其中00-1F、FF為控制字符。其它為英文字母、數(shù)字、標(biāo)點(diǎn)符號(hào)。
Latin1
編碼范圍00-FF,其中00-7F同ASCII,80-9F為控制符、9F-FF為字母和標(biāo)點(diǎn)符號(hào).
CP1252
微軟的企業(yè)標(biāo)準(zhǔn),補(bǔ)充了一些符號(hào)和歐元符號(hào),為L(zhǎng)atin1的超集。
GB2312
編碼范圍為A1A1-F7FE(剔除xx7F),共23940個(gè)碼位。其中很多區(qū)間沒有用到,而漢字使用的區(qū)間為B0A1-F7FE,其他為標(biāo)點(diǎn)符號(hào)和特殊字符。
除常用簡(jiǎn)體漢字字符外還包括希臘字母、日文平假名及片假名字母、俄語西里爾字母等字符,未收錄繁體中文漢字和一些生僻字。
對(duì)漢字進(jìn)行了分區(qū)管理,其中第一個(gè)字節(jié)為區(qū)位碼,包括下面區(qū)位。
01-09區(qū)為特殊符號(hào)。
16-55區(qū)為一級(jí)漢字,按拼音排序。
56-87區(qū)為二級(jí)漢字,按部首/筆畫排序。
10-15區(qū)及88-94區(qū)則未有編碼。
第二個(gè)字節(jié)為位字節(jié),01-94總計(jì)94個(gè)。
為什么實(shí)際選擇不是01-5E,而是選擇A1-F7的位置呢?
因?yàn)橛⑽目梢娮址麉^(qū)間為20-7F,加上128(也就是最高位為1)后得到的取件即是A1-FE
區(qū)位碼使用了0xA1-0xF7(把01-87區(qū)的區(qū)號(hào)加上0xA0),位字節(jié)使用了0xA1-0xFE(把01-94加上 0xA0)
GBK
編碼范圍為8140-FEFE,兼容GB2312,仍然有部分區(qū)間沒有用到。
GBK也支持希臘字母、日文假名字母、俄語字母等字符,但不支持韓語中的表音字符(非漢字字符)。GBK還收錄了GB2312不包含的 漢字部首符號(hào)、豎排標(biāo)點(diǎn)符號(hào)等字符。
CP936
CP936是微軟指定的標(biāo)準(zhǔn),屬于企業(yè)標(biāo)準(zhǔn),和GBK的有些許差別,絕大多數(shù)情況下可以把CP936當(dāng)作GBK的別名。
BIG5
Big5是雙字節(jié)編碼,高字節(jié)編碼范圍是0x81-0xFE,低字節(jié)編碼范圍是0x40-0x7E和0xA1-0xFE。和GBK相比,少了低字節(jié)是0x80-0xA0的組合。0x8140-0xA0FE是保留區(qū)域,用于用戶造字區(qū)。
Big5收錄的漢字只包括繁體漢字,不包括簡(jiǎn)體漢字,一些生僻的漢字也沒有收錄。
CP950
微軟的企業(yè)標(biāo)準(zhǔn),可以理解為是對(duì) Big5的擴(kuò)展。
GB18030
編碼范圍同GBK,補(bǔ)充了更多的字符,由于Unicode開始流行且GB18030補(bǔ)充的字符都比較生僻,所以實(shí)際使用上基本是GBK。
GB18030編碼是變長(zhǎng)編碼,有單字節(jié)、雙字節(jié)和四字節(jié)三種方式。GB18030的單字節(jié)編碼范圍是0x00-0x7F,完全等同與ASCII;雙字節(jié)編碼的范圍和GBK相同,高字節(jié)是0x81-0xFE,低字節(jié)的編 碼范圍是0x40-0x7E和0x80-FE;四字節(jié)編碼中第一、三字節(jié)的編碼范圍是0x81-0xFE,二、四字節(jié)是0x30-0x39。
Unicode
中文的編碼范圍為4E00-9FCF,其中9FC4-9FCF之間的區(qū)間沒有使用。
一個(gè)蛋疼的問題就是這個(gè)區(qū)間全部都是文字,中文標(biāo)點(diǎn)沒有包含在其中,中文標(biāo)點(diǎn)散落在各個(gè)位置。詳細(xì)請(qǐng)看http://blog.chinaunix.net/uid-12348673-id-3335307.html。
一些特殊的文字和中文部首以及一些特殊符號(hào)也不在此范圍內(nèi),詳細(xì)情況可以參考網(wǎng)址:http://www.cnblogs.com/sosoft/p/3456631.html
編碼方面的一些概念
大尾(big endian)和小尾(little endian)
大尾和小尾是CPU處理多字節(jié)數(shù)的不同方式。例如“漢”字的Unicode編碼是6C49。那么寫到文件里時(shí),究竟是將6C寫在前面,還是將49寫在前面?如果將6C寫在前面,就是big endian。還是將49寫在前面,就是little endian。
BOM
UTF-8以字節(jié)為編碼單元,沒有字節(jié)序的問題。UTF-16以兩個(gè)字節(jié)為編碼單元,在解釋一個(gè)UTF-16文本前,首先要弄清楚每個(gè)編碼單元的字節(jié)序。例如收到一個(gè)“奎”的Unicode編碼是594E,“乙”的Unicode編碼是4E59。如果我們收到UTF-16字節(jié)流“594E”,那么這是“奎”還是“乙”?
Unicode規(guī)范中推薦的標(biāo)記字節(jié)順序的方法是BOM,即Byte Order Mark。BOM是一個(gè)有點(diǎn)小聰明的想法:
在UCS編碼中有一個(gè)叫做"ZERO WIDTH NO-BREAK SPACE"的字符,它的編碼是FEFF。而FFFE在UCS中是不存在的字符,所以不應(yīng)該出現(xiàn)在實(shí)際傳輸中。UCS規(guī)范建議我們?cè)趥鬏斪止?jié)流前,先傳輸字符"ZERO WIDTH NO-BREAK SPACE"。
這樣如果接收者收到FEFF,就表明這個(gè)字節(jié)流是Big-Endian的;如果收到FFFE,就表明這個(gè)字節(jié)流是Little-Endian的。因此字符"ZERO WIDTH NO-BREAK SPACE"又被稱作BOM。
UTF-8不需要BOM來表明字節(jié)順序,但可以用BOM來表明編碼方式。字符"ZERO WIDTH NO-BREAK SPACE"的UTF-8編碼是EF BB BF(讀者可以用我們前面介紹的編碼方法驗(yàn)證一下)。所以如果接收者收到以EF BB BF開頭的字節(jié)流,就知道這是UTF-8編碼了。
Unicode的實(shí)現(xiàn)方式
Unicode只是進(jìn)行了編碼,也就是說只是一個(gè)碼表,至于具體怎么實(shí)現(xiàn),并沒有規(guī)定。
下面是Unicode的幾種實(shí)現(xiàn)方法。
UTF-8
| 0x0000~0x007F (0 ~ 127) | 1字節(jié) | 0xxxxxxx |
| 0x0080~0x07FF(128 ~ 2047) | 2字節(jié) | 110xxxxx 10xxxxxx |
| 0x0800~FFFF(2048 ~ 65535) | 3字節(jié) | 1110xxxx 10xxxxxx 10xxxxxx |
| 0x10000~1FFFFFF(65536 ~ 2097152) | 4字節(jié) | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
| 0x2000000~0x3FFFFFF | 5字節(jié) | 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx |
| 0x4000000~0x7FFFFFFF) | 6字節(jié) | 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx |
理論上說,UTF-8并沒有大小尾的困擾,所以并不需要BOM。
但是一些Windows應(yīng)用會(huì)指定大小尾,比如Notepad,而且Excel在沒有指定BOM的UTF-8文件進(jìn)行讀取時(shí)會(huì)使用Windows的codepage,從而出現(xiàn)錯(cuò)誤。
UTF-16
在Unicode基本多文種平面定義的字符(無論是拉丁字母、漢字或其他文字或符號(hào)),一律使用2字節(jié)儲(chǔ)存。而在輔助平面定義的字符,會(huì)以代理對(duì)(surrogate pair)的形式,以兩個(gè)2字節(jié)的值來儲(chǔ)存。
UTF-16比起UTF-8,好處在于大部分字符都以固定長(zhǎng)度的字節(jié) (2字節(jié)) 儲(chǔ)存,但UTF-16卻無法兼容于ASCII編碼。
可以認(rèn)為UTF-16是下面介紹的UCS-2的父集。在沒有輔助平面字符(surrogate code points)前,UTF-16與UCS-2所指的是同一的意思。但當(dāng)引入輔助平面字符后,就稱為UTF-16了?,F(xiàn)在若有軟件聲稱自己支援UCS-2編碼,那其實(shí)是暗指它不能支援在UTF-16中超過2bytes的字集。對(duì)于小于0x10000的UCS碼,UTF-16編碼就等于UCS碼。
如果一個(gè)UTF-16文件沒有指定BOM,默認(rèn)應(yīng)該是UTF-16BE,但是在Intel x86中卻是UTF-16LE。所以在現(xiàn)實(shí)世界中有很多的沒有指定大小尾的UTF-16卻是UTF-16LE。
UTF-32
每一個(gè)Unicode碼位使用恰好32位元。可以粗暴的認(rèn)為UTF-32和下面要介紹的UCS-4是等同的。
UCS-2
采用2個(gè)字節(jié),定長(zhǎng)的表示每一個(gè)字符,所以總計(jì)可以表示2^16個(gè)字符。
UCS-4
UCS-4根據(jù)最高位為0的最高字節(jié)分成2^7=128個(gè)group。每個(gè)group再根據(jù)次高字節(jié)分為256個(gè)plane。每個(gè)plane根據(jù)第3個(gè)字節(jié)分為256行(rows),每行包含256個(gè)cells。當(dāng)然同一行的cells只是最后一個(gè)字節(jié)不同,其余都相同。
group 0的plane 0被稱作Basic Multilingual Plane, 即BMP。或者說UCS-4中,高兩個(gè)字節(jié)為0的碼位被稱作BMP。
將UCS-4的BMP去掉前面的兩個(gè)零字節(jié)就得到了UCS-2。在UCS-2的兩個(gè)字節(jié)前加上兩個(gè)零字節(jié),就得到了UCS-4的BMP。而目前的UCS-4規(guī)范中還沒有任何字符被分配在BMP之外。
編碼轉(zhuǎn)換
請(qǐng)參考
字符編碼之UCS-2與Utf-8
UCS-2和UTF-8的互相轉(zhuǎn)換
操作系統(tǒng)使用編碼
從Windows2K開始,Win的系統(tǒng)內(nèi)核開始完全支持并完全應(yīng)用Unicode編寫,所有ANSI字符在進(jìn)入底層前,都會(huì)被相應(yīng)的API轉(zhuǎn)換成Unicode。
Linux 服務(wù)器上 UCS-2 編碼方式與 Winodws 不一致,以下是有關(guān)兩個(gè)平臺(tái) UCS-2 編碼的潛規(guī)則:
對(duì)于JAVA/.NET/Python等這些“新”的語言來說,內(nèi)置的字符串所使用的字符集已經(jīng)完全是Unicode最重要的是,世界上大多數(shù)程序用的字符集都是Unicode,因?yàn)閁nicode有利于程序國(guó)際化和標(biāo)準(zhǔn)化。
Python與編碼
我會(huì)接著寫另外一篇文章。
參考資料
轉(zhuǎn)載于:https://www.cnblogs.com/Free-Thinker/p/8309785.html
總結(jié)
- 上一篇: krpano·分组图片地图插件
- 下一篇: sublime text 3设置快捷键让