引言
这是每个程序员都应该无条件掌握的知识!
写在前面的话
在涉及到任何字符编码操做前,得先对字符编码有所了解,要否则只多是知其然而不知其因此然。html
本文属于 字符编码系列文章之一,更多请前往 字符编码系列。程序员
基本概念
字符
各类文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等。
也就是说,它是一个信息单位,一个数字是一个字符,一个文字是一个字符,一个标点符号也是一个字符。segmentfault
字节
字节是一个8bit的存储单元,取值范围是0x00~0xFF。
根据字符编码的不一样,一个字符能够是单个字节的,也能够是多个字节的。编码
字符集
字符的集合就叫字符集。不一样集合支持的字符范围天然也不同,譬如ASCII只支持英文,GB18030支持中文等等spa
在字符集中,有一个码表的存在,每个字符在各自的字符集中对应着一个惟一的码。可是同一个字符在不一样字符集中的码是不同的,譬如字符“中”在Unicode和GB18030中就分别对应着不一样的码(20013
与54992
)。设计
字符编码
定义字符集中的字符如何编码为特定的二进制数,以便在计算机中存储。
字符集和字符编码通常一一对应(有例外)3d
譬如GB18030既能够表明字符集,也能够表明对应的字符编码,它为了兼容ASCII码
,编码方式为code大于255
的采用两位字节(或4字节)来表明一个字符,不然就是兼容模式,一个字节表明一个字符。(简单一点理解,将它认为是如今用的的中文编码就好了)代理
字符集与字符编码的一个例外就是Unicode字符集,它有多种编码实现(UTF-8,UTF-16,UTF-32等)code
简要介绍
下面举些示例方便快速理解。htm
字符集与字符编码的快速区分
- ASCII码是一个字符集,同时它的实现也只有一种,所以它也能够指代这个字符集对应的字符编码
- GB18030是一个字符集,主要是中国人为了解决中文而发明制定的,因为它的实现也只有一种,因此它也能够指代这个字符集对应的字符编码
- Unicode是一个字符集,为了解决不一样字符集码表不一致而推出的,统一了全部字符对应的码,所以在这个规范下,全部字符对应的码都是一致的(统一码),可是统一码只规定了字符与码表的一一对应关系,却没有规定该如何实现,所以这个字符集有多种实现方式(UTF-8,UTF-18,UTF-32),所以这些实现就是对应的字符编码。
也就是说,Unicode统一约定了字符与码表直接一一对应的关系,而UTF-8是Unicode字符集的一种字符编码实现方式,它规定了字符该如何编码成二进制,存储在计算机中。
字符集与字符编码发展简史
这段资料主要借鉴了参考连接中的描述,只对大概发展作一个简要概述,每个编码的详细介绍请参考系列文章目录里的其它文章。
欧美的单字节字符编码发展
- 美国人发明了计算机,使用的是英文,因此一开始就设计了一个几乎只支持英文的字符集
ASCII码
(1963 发布),有128个码位,用一个字节便可表示,范围为00000000-01111111
- 后来发现码位不够,因而在这基础上进行拓展,256个字符,取名为
EASCII(Extended ASCII)
,也能一个字节表示,范围为00000000-11111111
- 后来传入欧洲,发现这个标准并不适用于一些欧洲语言,因而在
ASCII
(最原始的ASCII)的基础上拓展,造成了ISO-8859标准(国际标准,1998年发布),跟EASCII相似,兼容ASCII。而后,根据欧洲语言的复杂特性,结合各自的地区语言造成了N个子标准,ISO-8859-一、ISO-8859-二、...
。
兼容性简直使人发指。
亚洲,只能双字节了
- 计算机传入亚洲后,国际标准已被彻底不够用,东亚语言随便一句话就已经超出范围了,也是这时候亚洲各个国家根据本身的地区特点,有发明了本身地图适用的字符集与编码,譬如中国大陆的GB2312,中国台湾的BIG5,日本的Shift JIS等等
这些编码都是用双字节来进行存储,它们对外有一个统称(ANSI-American National Standards Institute),也就是说GB2312或BIG5等都是ANSI在各自地区的不一样标准。
Unicode,一统天下
- 到了全球互联网时代,不一样国家,不一样地区须要进行交互,这时候因为各自编码标准都不同,彼此之间都是乱码,没法良好的沟通交流,因而这时候ISO组织与统一码联盟分别推出了UCS(Universal Multiple-Octet Coded Character Set)与Unicode。后来,二者意识到没有必要用两套字符集,因而进行了一次整合,到了Unicode2.0时代,Nnicode的编码和UCS的编码都基本一致(因此后续为了简便会赞成用Unicode指代),这时候全部的字符均可以采用同一个字符集,有着相同的编码,能够愉快的进行交流了。
- 须要注意的是UCS标准有本身的格式,如UCS-2(双字节),UCS-4(四字节)等等
而Unicode也有本身的不一样编码实现,如UTF-8,UTF-16,UTF-32等等
其中UTF-16能够认为是UCS-2的拓展,UTF-32能够认为是UCS-4的拓展,而Unicode能够认为是Unicode最终用来制霸互联网的一种编码格式。
在中国,GB系列的发展
- 在计算机传入中国后,1980年,中国国家标准总局发布了第一个汉字编码国家标准GB2312(2312是标准序号),采用双字节编码,里面包括了大部分汉字,拉丁字母,日文假名以及全角字符等。
- 然而,随着程序的发展,逐渐发现GB2312已经不知足需求了,因而1993年又推出了一个GBK编码(汉字国标扩展码),彻底兼容GB2312标准。而且包括了BIG5的全部汉字,与1995年发布。
同时GBK也涵盖了Unicode全部CJK汉字,因此也能够和Unicode作一一对应。
- 后来到了2000年,又推出了一个全新的标准 GB 18030,它不只拓展了新的字符,如支持中国少数名族文字等,并且它采用了单字节,双字节,四字节三种编码方式,因此彻底兼容ASCII码与GBK码。
到了2005年,这一标准有进行了拓展,推出了GB18030-2005,剧本涵盖全部汉字,也就是说,如今使用的国标标准码就是GB18030-2005了。
不一样字符编码的字符是如何进行转换的
- 若是是相同字符集,因为相同字符集中的码都是同样的,因此只须要针对不一样的编码方式转变而已。譬如UTF-16转UTF-8,首先会取到当前须要转换的字符的Unicode码,而后将当前的编码方式由双字节(有4字节的拓展就不赘述了),变为变长的1,2,3等字节
- 若是是不一样的字符集,因为不一样字符集的码是不同的,因此须要各自的码表才能进行转换。譬如UTF-16转GBK,首先须要取到当前须要转换的字符的Unicode码,而后根据Unicode和GBK码表一一对应的关系(只有部分共同都有的字符才能在码表中查到),找到它对应的GBK码,而后用GBK的编码方式(双字节)进行编码
编年史
注意,此编年史引用自来源连接中的内容(作了部分修改与更新)-http://www.jianshu.com/p/bd7a6c508c33
- ASCII
1960 开发
1963 发布
1986 最后一次更新
- ISO-8859-1
1998 发布
- GB2312
1980 发布
- GBK
1993 发布
- GB18030
2000年3月17日发布 GB18030-2000
2001年的1月强制执行GB18030-2000
2005年发布GB18030-2005
- UCS与Unicode
1984年 UCS开始制定标准
1991年10月 Unicode1.0发布
1992年1月 Unicode与ISO 10646国际编码标准正式合做,发展一套通用 编码标准
1993年 ISO组织发表UCS(标准编号ISO 10646)国际编码标准的第一个版 本
1993年6月 修订了Unicode 1.0,发布Unicode 1.1
1996 年7月 发布Unicode2.0(实现了代理机制(UTF-16),这时候Unicode和UCS能够近似认为同样
- UTF-16
1996年7月 发布
- UTF-8
1993 发布
1996年 微软的CAB(MS Cabinet)在UTF-8标准正式落实前就明确允许在任何地方使用UTF-8编码系统
2008 流行
UTF-8制霸互联网过程

附录
博客
初次发布2017.05.03
于我的博客
http://www.dailichun.com/2017/05/03/char_charset_charEncoding.html
参考资料