给妹子讲python-S01E07字符编码历史观-从ASCII到Unicode

欢迎关注公众号:python数据科学家python

【要点抢先看】编程

1.字符编码与解码的概念
2.ASCII编码到Unicode编码的发展过程
3.容易混淆的字符编码与字符代码ruby

【妹子说】上两集基本上让咱们熟悉了字符串的常见用法,不过倒也让我想起一直以来困惑的一些概念:ASCII码、Unicode、字符编码什么的,一直没搞明白过,今天不妨就来介绍一下这方面的内容吧。app

关于字符编码的概念太多太杂,当ASCII、GB23十二、Unicode、UTF-八、UTF-1六、编码、解码等诸多名词一股脑堆上来时,确实容易让人迷糊。编码

为了把这些问题讲清楚,今天换一种讲法,不讲编程,只讲故事,从历史维度,在时间轴上梳理计算机在不一样语言国家不断发展的过程,以此来完全搞清楚这些概念。spa

字符编码与解码是什么?设计

计算机本身能理解的“语言”是二进制数,最小的信息标识是二进制位,8个二进制位表示一个字节;而咱们人类所能理解的语言文字则是一套由英文字母、汉语汉字、标点符号字符、阿拉伯数字等等不少的字符构成的字符集。若是要让计算机来按照人类的意愿进行工做,则必须把人类所使用的这些字符集转换为计算机所能理解的二级制码,这个过程就是编码,他的逆过程称为解码code

ASCII到Unicode的演进过程orm

计算机最开始在美国被发明使用,须要编码的字符集并非很大,无外乎英文字母、数字和一些简单的标点符号,所以采用了一种单字节编码系统。在这套编码规则中,人们将所需字符集中的字符一一映射到128个二进制数上,这128个二进制数最高位为0,利用剩余低7位组成00000000~01111111(0X00~0X7F)。cdn

0X00到0X1F这32个二进制数来对控制字符或通讯专用字符(如LF换行、DEL删除、BS退格)进行编码,0X20到0X7F共96个二进制数用来对阿拉伯数字、英文字母大小写和下划线、括号等符号进行编码。将这套字符集映射到0X00~0X7F二进制码的过程就称为基础ASCII编码,经过这个编码过程,计算机就将人类的语言转化为本身的语言存储起来;反之,从磁盘中读取二级制数并转化为字母数字等字符以供显示的过程就是解码了。

随着计算机被迅速推广使用,欧洲非英语国家的人们发现这套由美国人设计的字符集不够用了,好比一些带重音的字符、希腊字母等都不在这个字符集中,因而扩充了ASCII编码规则,将本来为0的最高位改成1,所以扩展出了10000000~11111111(0X80~0XFF)这128个二进制数。这其中,最优秀的扩展方案是ISO 8859-1,一般称之为Latin-1。Latin-1利用128~255这128个二进制数,包括了足够的附加字符集来涵盖基本的西欧语言,同时在0~127的范围内兼容ASCII编码规则。

随着使用计算机的国家愈来愈多,天然而然须要编码的字符集就愈来愈庞大,早先的ASCII编码字符集因为受到单字节的限制,其容量就远远不够了,比方说面对成千上万的汉字,其压力可想而知。所以中国国家标准总局发布了一套《信息交换用汉字编码字符集》的国家标准,其标准号就是GB 2312—1980。这个字符集共收入汉字6763个和非汉字图形字符682个,采用两个字节对字符集进行编码,并向下兼容ASCII编码方式。简言之,整个字符集分红94个区,每区有94个位,分别用一个字节对应表示相应的区和位。每一个区位对应一个字符,所以可用所在的区和位来对汉字进行两字节编码。再后来生僻字、繁体字及日韩汉字也被归入字符集,就又有了后来的GBK字符集及相应的编码规范,GBK编码规范也是向下兼容GBK2312的。

在中国发展的同时,计算机在全世界各个国家不断普及,不一样的国家地区都会开发出本身的一套编码系统,所以编码系统五花八门,这时候问题就开始凸显了,特别是在互联网通讯的大环境下,装有不一样编码系统的计算机之间通讯就会彼此不知道对方在“说”些什么,按照A编码系统的编码方式将所需字符转换成二进制码后,在B编码系统的计算机上解码是没法获得原始字符的,相反会出现一些出人意料的古怪字符,这就是所谓的乱码

那么统一字符编码的需求就迫切摆在了你们眼前,为了实现跨语言、跨平台的文本转换和处理需求,ISO国际标准化组织提出了Unicode的新标准,这套标准中包含了Unicode字符集和一套编码规范。Unicode字符集涵盖了世界上全部的文字和符号字符,Unicode编码方案为字符集中的每个字符指定了统一且惟一的二进制编码,这就能完全解决以前不一样编码系统的冲突和乱码问题。这套编码方案简单来讲是这样的:编码规范中含有17个组(称为平面),每个组含有65536个码位(例如组0就是0X0000~0XFFFF),每个码位就惟一对应一个字符,大部分的字符都位于字符集平面0的码位中,少许位于其余平面。

字符编码和字符代码的概念区分

既然提到了Unicode编码,那么经常与之相伴的UTF-8,UTF-16编码方案又是什么?其实到目前为止咱们都一直混淆了两个概念,即字符代码字符编码,字符代码是特定字符在某个字符集中的序号,而字符编码是在传输、存储过程中用于表示字符的以字节为单位的二进制序列。ASCII编码系统中,字符代码和字符编码是一致的,好比字符A,在ASCII字符集中的序号,也就是所谓的字符代码是65,存储在磁盘中的二进制比特序列是01000001(0X41,十进制也是65),另外的,如在GB2312编码系统中字符代码和字符编码的值也是一致的,因此无形之中咱们就忽略了两者的差别性。

而在Unicode标准中,咱们目前使用的是UCS-4,即字符集中每个字符的字符代码都是用4个字节来表示的,其中字符代码0~127兼容ASCII字符集,通常的通用汉字的字符代码也都集中在65535以前,使用大于65535的字符代码,即须要超过两个字节来表示的字符代码是比较少的。所以,若是仍然依旧采用字符代码和字符编码相一致的编码方式,那么英语字母、数字本来仅需一个字节编码,目前就须要4个字节进行编码,汉字本来仅需两个字节进行编码,目前也须要4个字节进行编码,这对于存储或传输资源而言是很不划算的。

所以就须要在字符代码和字符编码间进行再编码,这样就引出了UTF-八、UTF-16等编码方式。基于上述需求,UTF-8就是针对位于不一样范围的字符代码转化成不一样长度的字符编码,同时这种编码方式是以字节为单位,而且彻底兼容ASCII编码,即0X00-0X7F的字符代码和字符编码彻底一致,也是用一个字节来编码ASCII字符集,而经常使用汉字在Unicode中的字符代码是4E00-9FA5,在文末的对应关系中咱们看到是用三个字节来进行汉字字符的编码。UTF-16同理,就是以16位二进制数为基本单位对Unicode字符集中的字符代码进行再编码,原理和UTF-8一致。

所以,咱们能够看出,在目前全球互联的大背景下,Unicode字符集和编码方式解决了跨语言、跨平台的交流问题,同时UTF-8等编码方式又有效的节约了存储空间和传输带宽,于是受到了极大的推广应用。

【妹子说】故事讲的不错啊,以前对这些概念感受是一团乱麻,这一集讲清楚了字符编码的发展历史,容易让人明白为何某一时刻就出现了某种编码方式,搞清楚了前因后果,对字符编码就好理解了。

附表:

Unicode字符代码与UTF-8编码的对应关系

0000 0000-0000 007| 0xxxxxxx

0000 0080-0000 07FF |
 110xxxxx 10xxxxxx

0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx

0001 0000-0010 FFFF |
 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
复制代码

公众号二维码:python数据科学家: