字符编码是将字符集中的字符编码指定为集合中的对象,以便文本在计算机中存储并通过网络进行传递。目前世界上有各种各样的字符编码方案,其中一些只能用于特定的语言,还有一些则可以用于多种语言。下面介绍几种常用的字符编码方案。
ASCII(American Standard Code for Information Interchange)即美国国家信息交换标准代码,这种编码方案使用7位或8位二进制数进行编码,最多可以给256个字符(包括字母、数字、标点符号、控制字符及其他符号)分配数值,数值范围为0~255。ASCII用于在不同计算机硬件和软件系统中实现数据传输标准化。ASCII划分为标准ASCII(0~127)和附加的扩充ASCII(128~255)两个集合。
标准ASCII字符集一共有128个字符,其中有96个可打印字符,包括字母、数字以及标点符号等,另外还有32个控制字符。例如,65表示大写字母A,97表示小写字母a,49表示数字1等。标准ASCII使用7位二进制数对字符进行编码,对应的ISO(International Organization for Standardization,国际标准化组织)标准为ISO 646标准。虽然标准ASCII是7位编码,但由于计算机基本处理单位为字节,所以一般仍使用一个字节来存放一个ASCII字符。每一个字节中多余出来的一位(最高位)在计算机内部通常为0,在数据传输时可以作奇偶校验位。
由于标准ASCII字符集字符数目有限,在实际应用中无法满足要求,所以,国际标准化组织又制定了ISO 2022标准,它规定了在保持与ISO 646兼容的前提下将ASCII字符集扩充为8位代码的统一方法。ISO陆续制定了一批适用于不同地区的扩充ASCII字符集,每种扩充ASCII字符集都可以扩充128个字符,这些扩充字符的编码均为高位为1的8位代码,称为扩展ASCII码。
【例3.1 】 输出ASCII33~126对应的字符。
【算法分析】
对于给定的ASCII值可以使用Python内置函数chr()求出相应的字符;对于给定范围内的ASCII值,可以通过调用range()函数来生成一个数值序列,然后使用for循环来遍历这个数值序列。
【程序代码】
【运行结果】
中文字符数量很多而且结构复杂,需要使用多字节编码的字符集。常用的中文编码方案有以下几种。
1)GB 2312:是1981年5月发布的简体中文汉字编码国家标准。GB 2312对汉字采用双字节编码,收录了6763个汉字和682个非汉字图形字符。整个字符集分成94个区,每区有94个位。每个区位上只有一个字符,因此可用所在的区和位对汉字进行编码,称为区位码。将十六进制的区位码加上2020H即得到国标码,再加上8080H,则得到常用的计算机机内码。
2)BIG5:是中国台湾地区繁体中文标准字符集,采用双字节编码,一共收录了13053个中文字,于1984年开始实施。
3)GBK:是1995年12月发布的汉字编码国家标准,是对GB 2312编码的扩充,对汉字采用双字节编码,编码范围为8140~FEFE,首字节在81~FE之间,尾字节在40~FE之间,剔除xx7F线,总计23940个码位,一共收录21886个汉字和883个图形符号,其中包括GB 2312中的全部汉字、非汉字符号、BIG5中的全部汉字,与ISO 10646相应的国家标准GB 13000中的其他CJK汉字,984个其他汉字、部首和符号。
4)GB18030:是2000年3月发布的汉字编码国家标准,是对GBK编码的扩充,覆盖了中文、日文、朝鲜文和中国少数民族文字,其中收录了27484个汉字。GB 18030字符集采用单字节、双字节和四字节3种方式对字符编码,兼容GBK和GB 2312字符集。
Unicode是计算机科学领域内的一项业界标准,包括字符集和编码方案等。Unicode是为了解决传统字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。Unicode于1990年开始被研发,于1994年正式被公布。
Unicode是可以容纳世界上所有文字和符号的字符编码方案。目前的Unicode字符分为17组,每组称为一个平面,每个平面有65536个码位,但目前只用了少数平面。
Unicode 5.0.0版本定义了238605个码位,剔除一些专用区,剩下99089个已定义码位,在这些码位上分布着Unicode定义的99089个字符。在Unicode字符中一共有71226个汉字,汉字的编码范围为4E00~9FA5。
Unicode是一种编码标准,它只是规定了字符的二进制代码,却没有规定二进制代码如何存储。通常所说的Unicode编码实际上是指UCS编码方式,即直接存入字符的Unicode二进制代码。
【例3.2 】 按照Unicode编码从小到大输出前100个汉字及其Unicode编码。
【算法分析】
使用Python内置函数ord()和chr(),可以实现字符与ASCII或Unicode编码之间的相互转换,ord()函数可将一个字符转换相应的ASCII或Unicode编码值,chr()函数则可将一个整数转换为相应的Unicode字符。对于给定范围内的Unicode编码值,可以通过调用range()函数来生成一个数值序列,然后使用for循环来遍历这个数值序列。
【程序代码】
【运行结果】
UTF(Unicode Transformation Format)是Unicode传送格式,也就是将Unicode文件转换成字节的传送流。UTF-8就是为传送Unicode字符而设计的一种编码方案,也是目前应用最广泛的一种Unicode的实现方式。
UTF-8采用的是一种变长编码方式,即使用1~4B表示一个符号,根据不同的符号选择不同长度的字节表示,其具体编码规则如下:对于单字节符号,字节的第一位为0,后面7位为这个符号的Unicode编码;对于 n 字节符号( n >1),第一个字节的前 n 位均为1,第 n +1位为0,后面字节的前两位均为10,剩下的二进制位全部为该符号的Unicode编码。
从Unicode编码到UTF-8编码的转换规则详见表3-1。
表3-1 UTF-8编码转换规则
对于英语字母而言,因为其Unicode编码小于80H,所以其UTF-8编码与ASCII编码是相同的,只需要使用一个字节的UTF-8编码传送即可。例如,大写字母“A”的UTF-8编码和ASCII编码都是65,小写字母“a”的UTF-8编码和ASCII编码都是97。
对于汉字而言,因为其 Unicode 编码范围为 4E00~9FA5,所以需要使用 3B 模板1110xxxx 10xxxxxx 10xxxxxx。例如,“啊”字的 Unicode 编码为 554AH,换算成二进制是0101 010101 001010,将这个字节流代入3B模板可以得到11100101 10010101 10001010,这便是“啊”字的 UTF-8 编码 E5958AH。用同样的方法可以得到“汉”字的 UTF-8 编码为E6B189H。
【例3.3 】 从键盘输入一个汉字,然后求出其Unicode、UTF-8和GBK编码,以及这个汉字以不同方式编码时的长度。
【算法分析】
若要判断输入的字符是不是汉字,使用成员运算符in检查其Unicode编码是否位于汉字的编码范围内即可。在Python中,字符串默认使用Unicode编码方式。如果要获取字符串的其他编码(例如GBK、UTF-8等),可以通过调用字符串对象的encode()函数来实现,此时将以字节对象形式返回字符串的编码。字符串长度可以通过调用Python内置函数len()求出。
【程序代码】
【运行结果】
再次运行程序: