1、编码是什么html
编码为了某种目的把信息从一种形式集合转换为另外一种形式集合的过程,古时的鸣金收兵,从某种意义上讲也是一种编码,将帅发出了退兵的命令,为了让更多的人可以知道这个命令,传令兵把这个信息转换为了锣声,传递了出去linux
与编码相对的还有解码,解码是根据某种规则将信息恢复到原状的过程,士兵以前都接收过训练,在听到锣声以后,明白到锣声表明退兵,便开始执行这一命令。git
旗语,电报中的莫斯电码等等,这些东西里面也包含了编码github
2、关于字符集和字符编码web
由于计算机中的信息都是用二进制数表示的,因此咱们必须将汉字、英文按照必定的规则表示出来储存在计算机中windows
因此字符编码就是为了信息处理,将天然语言中的一个集合与另外一个集合如(如号码和电脉冲)进行配对,创建对应关系,常见的编码方式有ASCII,GBK,GB2312,utf8,utf16,utf32等网络
字符集就是是一个系统支持的全部抽象字符的集合,字符是各类文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等。,每个抽象字符都会对应一个惟一的codepoint,常见字符集有:ASCII字符集、GB2312字符集、BIG5字符集、GB18030字符集、Unicode字符集等。ide
使用1个字节编码的字符集,叫作单字节字符集(SBCS - Single-Byte Character Set)。编码
使用一、二、三、4等不等字节编码的字符集,叫作多字节字符集(MBCS - Multi-Byte Character Set)。idea
3、编码的历史
早期的时候,计算机的字符编码并无统一的标准,不少都是来自电报时产生的编码方式,如博多电码,霍勒内斯码等,
EBCDIC
1962年 AT&T将第一部商用远程通信卫星-Telstar I 放入环绕地球的轨道。同年,IBM公司建立了一套编码标准,EBCDIC,根据早期打孔机式的二进化十进数(BCD, Binary Coded Decimal)排列而成,定义了256种不一样的8位字符。
ASCII
1963年 ASCII做为EBDIC替代产品而发展起来。ASCII由96个大小写字母、数字加上32个非打印字符组成
ASCII编码只占用1个字节,标准 ASCII 码是 7 位编码,但为了凑足一字节,多出来的一位,最高位一般设置为0。
扩展Ascii码
ASCII的缺点就是表示的东西太少了,只能用于显示现代美国英语
所以人们便利用ASCII的第8位产生了新的编码方式,第一个iso-8859-1字符集。又叫:Latin-1 编码(西欧编码),扩展ASCII字符集使用8位(bits)表示一个字符,其中0-127字符及位置编码彻底兼容ascii码。只是在128-255位置编入了新字符,解决了部份西欧语言的显示问题。
后来陆续出了iso-8859-2…-15字符集。都彻底兼容ascii码。
因为扩展ASCII只是解决了部分西欧语言的显示问题,表示字符仍是太少,对其余语言无能为力,所以各个国家又为本身国家的文字制定了一系类标准
GB2312
1980年,中国制定了GB2312-80,一共收录了 7445 个字符,包括 6763 个汉字和 682 个其它符号。
GB2312规定一个小于127的字符的意义与原来相同,但两个大于127的字符连在一块儿时,就表示一个汉字,前面的一个字节(称之为高字节)从0xA1用到 0xF7,后面一个字节(低字节)从0xA1到0xFE,这样就能够组合出大约7000多个简体汉字了。在这些编码里,还把数学符号、罗马希腊的 字母、日文的假名们都编进去了,连在ASCII里原本就有的数字、标点、字母都通通从新编了两个字节长的编码,这就是常说的"全角"字符,而原来在127号如下的那些就叫"半角"字符了。
GB2312使用了2个字节进行编码
因为GB2312只收录了6763个汉字,一些GB2312推出之后才简化的汉字“啰”,镕”和一些罕见字并未收录进去,1993年,有出现了“GB 13000.1-93”,简称为GB13000。
GB13000使用2个字节进行编码,收录中国大陆、台湾、日本及韩国通用字符集的汉字,总共有20,902个。
GBK是对GB2312的扩展,最先实现于windows95简体中文版,使用2个字节进行编码中文字符,英文字符和以前表示同样,所以想下兼容ASCII,收录了 21886 个符号,它分为汉字区和图形符号区。汉字区包括 21003 个字符。
因为GBK自身并不是国家标准,只是曾由国家技术监督局标准化司、电子工业部科技与质量监督司公布为“技术规范指导性文件”。
而原始GB13000一直未被业界采用,因此2000年,国家推出了GB18030-2000,简称GB18030,技术上兼容GBK而非GB13000,取代了 GBK1.0,成了正式的国家标准。
该标准使用1,2,4个字节进行字符编码
最近版本已经收录了 70244 个汉字
规定PC平台必须支持 GB18030 ,对嵌入式产品暂不做要求。所以有的手机、MP3只支持 GB2312。
在技术编码方面上,演化顺序为:
ASCII ⇒ GB2312 ⇒ GBK ⇒ GB18030
Big5
Big5,又称为大五码或五大码,是使用繁体中文社区中最经常使用的字符编码标准,Big5使用2个字节进行编码,共收录13,060个汉字。
在这个时候,字符集和字符编码其实并无彻底区分开,直到UNICODE字符集的出现,字符集和字符编码这两个概念才区分的出来
UNICODE
每个国家都有本身的一套编码方案,这些东西在本地使用并无问题,当时一旦出如今网络,因为不兼容,互相访问的时候便会出现乱码了,为了解决这个问题,便产生了Unicode,
Unicode字符集(统一码、万国码、单一码、标准万国码),每一个数字表明惟一的至少在某种语言中使用的符号。(并非全部的数字都用上了,可是总数已经超过了65535,因此2个字节的数字是不够用的。)被几种语言共用的字符一般使用相同的数字来编码,除非存在一个在理的语源学(etymological)理由使之不这样作。
unicode定义了17个平面,每一个平面包括65536个码位
平面0 (0000-FFFF)0-65536的码位叫作基本多文本平面(BMP),其他的16个平面叫作辅助平面,
上述使用4字节的数字来表达每一个字母、符号,或者表意文字(ideograph),每一个数字表明惟一的至少在某种语言中使用的符号的编码方案,称为UTF-32。UTF-32又称UCS-4是一种将Unicode字符编码的协定,对每一个字符都使用4字节。就空间而言,是很是没有效率的。
这种方法有其优势,最重要的一点就是能够在常数时间内定位字符串里的第N个字符,由于第N个字符从第4×Nth个字节开始。虽然每个码位使用固定长定的字节看似方便,它并不如其它Unicode编码使用得普遍。
尽管有Unicode字符很是多,可是实际上大多数人不会用到超过前65535个之外的字符。所以,就有了另一种Unicode编码方式,叫作UTF-16,UTF-16将0–65535范围内的字符编码成2个字节,若是真的须要表达那些不多使用的"星芒层(astral plane)"内超过这65535范围的Unicode字符,则须要使用一些特殊的技巧来实现。UTF-16编码最明显的优势是它在空间效率上比UTF-32高两倍,由于每一个字符只须要2个字节来存储(除去65535范围之外的),而不是UTF-32中的4个字节。
UTF-16的缺点是每一个字符都须要使用了2个字节来表示,所以并不能和ASCII兼容。
关于BOM
由于UTF-32和UTF-16使用4字节或字节进行编码,所以传输的时候便会出现字节序的问题,例如“奎”的Unicode编码是594E,“乙”的Unicode编码是4E59。若是咱们收到UTF-16字节流“594E”,那么这是“奎”仍是“乙”?这是UTF-16文件开头的BOM就有做用了。为了解决这个问题,多字节的Unicode编码方式定义了一个"字节顺序标记(Byte Order Mark)",它是一个特殊的非打印字符,你能够把它包含在文档的开头来指示你所使用的字节顺序,FEFF。若是收到一个以字节FF FE开头的UTF-16编码的文档,你就能肯定它的字节顺序是单向的(one way)的了;若是它以FE FF开头,则能够肯定字节顺序反向了。
UTF-8(8-bit Unicode Transformation Format)是一种针对Unicode的可变长度字符编码(定长码),也是一种前缀码。它使用一至四个字节进行字符编码,能够用来表示Unicode标准中的任何字符,且其编码中的第一个字节和ASCII兼容,这使得原来处理ASCII字符的软件无须或只须作少部份修改,便可继续使用。所以,它逐渐成为电子邮件,网页和其余储存或传送文字的应用中,优先采用的编码。互联网工程小组(IETF)要求全部互联网都必须支持UTF-8编码。utf8的编码中也有bom,EF BB BF,不过因为utf8没有字节序的问题,因此这个能够用了确认这个文件是用utf8编码的
优势
UTF-8是ASCII的一个超集。因此现存的ASCII文本不须要转换,也是一个合法的UTF-8字符串,为传统的扩展ASCII字符集设计的软件一般能够不经修改或不多修改就能与UTF-8一块儿使用。
缺点
由于每一个字符使用不一样数量的字节编码,因此寻找串中第N个字符是一个O(N)复杂度的操做 — 即,串越长,则须要更多的时间来定位特定的字符。同时,还须要位变换来把字符编码成字节,把字节解码成字符。
4、UTF-8字符编码规则
若是一个字节的第一位为0,那么表明当前字符为单字节字符,占用一个字节的空间。0以后的全部部分(7个bit)表明在Unicode中的序号也就是codepoint。
若是一个字节以110开头,那么表明当前字符为双字节字符,占用2个字节的空间。110以后的全部部分(5个bit)加上后一个字节的除10外的部分(6个bit)表明在Unicode中的序号。且第二个字节以10开头
若是一个字节以1110开头,那么表明当前字符为三字节字符,占用3个字节的空间。1110以后的全部部分(4个bit)加上后两个字节的除10外的部分(12个bit)表明在Unicode中的序号。且第2、第三个字节以10开头
若是一个字节以11110开头,那么表明当前字符为四字节字符,占用4个字节的空间。11110以后的全部部分(3个bit)加上后两个字节的除10外的部分(12个bit)表明在Unicode中的序号。且第2、第三个字节以10开头
Byte1 | Byte2 | Byte3 | Byte4 |
0XXX XXXX | |||
110X XXXX | 10XX XXXX | ||
1110XXXX | 10XX XXXX | 10XX XXXX | |
1111 0XXX | 10XX XXXX | 10XX XXXX | 10XX XXXX |
例如
utf8编码对应的十六进制 | utf8编码对应的二进制 | 在Unicode字库序号的二进制 | 在Unicode字库序号的十六进制 | |
百 | e799 be | 11100111 10011001 10111110 | 0111 0110 0111 1110 | 767E |
度 | e5ba a6 | 11100101 10111010 10100110 | 0101 1110 1010 0110 | 5EA6 |
关于UTF8和UTF8 mb4
MySQL 5.5.3版本开始 MySQL中支持UTF8和UTF8mb4
UTF8mb4是UTF8的超集,MySQL 5.5.3以前的UTF8最多占用3个字节,UTF8mb4是对UTF8的扩充,最多占用4个字节
5、一个实例
咱们建立一个文本文件,内容以下,并把它保存成utf8的格式
而后咱们用UltraEdit打开后查看其16进制的内容
最前面的EF BB BF 表示这个文件是用utf8编码的
由于UTF-8是ASCII的一个超集。因此现存的ASCII文本不须要转换,也是一个合法的UTF-8字符串
对应1,2,3,4,5,6,7,8 ,\r\n原有的ASCII就是其合法的编码
31 32 33 34 35 36 37 38是12345678对应的编码
0D 0A是windows下的换行符\r\n
61 62 63 64 65 66 67是abcdefg对应的编码
0D 0A是windows下的换行符\r\n
对于E7 99 BE E5 BA A6经过上面的介绍咱们能够知道其对应着百度两个字
utf8编码对应的十六进制 | utf8编码对应的二进制 | 在Unicode字库序号的二进制 | 在Unicode字库序号的十六进制 | |
百 | e799 be | 11100111 10011001 10111110 | 0111011001111110 | 767E |
度 | e5ba a6 | 11100101 10111010 10100110 | 0101111010100110 | 5EA6 |
6、参考文献
http://cenalulu.github.io/linux/character-encoding/ 十分钟搞清字符集和字符编码
http://tgideas.qq.com/webplat/info/news_version3/804/808/811/m579/201307/218730.shtml 字符编码的前世此生
http://blog.csdn.net/gqqnb/article/details/6266542 精确解释Unicode
http://superuser.com/questions/537229/what-character-encodings-were-used-before-1963
https://zh.wikipedia.org/wiki/%E7%BC%96%E7%A0%81
http://www.crifan.com/files/doc/docbook/char_encoding/release/htmls/enc_eascii_iso8859.html