python 字符编码
字符编码介绍
什么是字符编码
计算机要想工作必须通电,即用‘电’驱使计算机干活,也就是说‘电’的特性决定了计算机的特性。电的特性即高低电平(人类从逻辑上将二进制数1对应高电平,二进制数0对应低电平),关于磁盘的磁特性也是同样的道理。结论:计算机只认识数字。
很明显,我们平时在使用计算机时,用的都是人类能读懂的字符(用高级语言编程的结果也无非是在文件内写了一堆字符),如何能让计算机读懂人类的字符?
必须经过一个过程:
- 字符 --------》翻译过程 -------》数字
总而言之,字符编码是将人类的字符编码成计算机能识别的数字,这种转换必须遵循一套固定的标准,该标准无非是人类字符与数字的对应关系,称之为字符编码表。
字符编码发展史与分类
计算机由美国人发明,最早的字符编码为ASCII,只规定了英文字母数字和一些特殊字符与数字的对应关系。最多只能用 8 位来表示(一个字节),即:2**8 = 256,所以,ASCII码最多只能表示 256 个符号。
当然我们编程语言都用英文没问题,ASCII够用,但是在处理数据时,不同的国家有不同的语言,中国人会加入中文,日本人会在自己的程序中加入日文,韩国人也是。
但是要表示中文,ASCII是不可能表达完的(连小学生都认识两千多个汉字),解决方法只有一个,就是一个字节用>8位2进制代表,位数越多,代表的变化就多,这样,就可以尽可能多的表达出不同的汉字。
所以中国人规定了自己的标准编码gb2312,规定了包含中文在内的字符与数字的对应关系。
日本人规定了自己的Shift_JIS编码;韩国人规定了自己的Euc-kr编码
这时候问题出现了,精通18国语言的小周同学谦虚的用8国语言写了一篇文档,那么这篇文档,按照哪国的标准,都会出现乱码(因为此刻的各种标准都只是规定了自己国家的文字在内的字符跟数字的对应关系,如果单纯采用一种国家的编码格式,那么其余国家语言的文字在解析时就会出现乱码)。所以迫切需要一个世界的标准(能包含全世界的语言)于是Unicode应运而生。
ascii用1个字节(8位二进制)代表一个字符;Unicode常用2个字节(16位二进制)代表一个字符,生僻字需要用4个字节。
例:字母x,用ascii表示是十进制的120,二进制0111 1000。
汉字中已经超出了ASCII编码的范围,用Unicode编码是十进制的20013,二进制的01001110 00101101。
字母x,用Unicode表示二进制0000 0000 0111 1000,所以Unicode兼容ascii,也兼容万国,是世界的标准。
这时候乱码问题消失了,所有的文档我们都使用但是新问题出现了,如果我们的文档通篇都是英文,你用Unicode会比ascii耗费多一倍的空间,在存储和传输上十分的低效。
本着节约的精神,往硬盘存入数据时,把Unicode编码转化为“可变长编码”的UTF-8(Unicode Transformation Format-8)编码。UTF-8编码把一个Unicode字符根据不同的数字大小编码成1-6个字节,常用的英文字母被编码成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节。如果你要传输的文本包含大量英文字符,用UTF-8编码就能节省空间:
字符 | ASCII | Unicode | UTF-8 |
---|---|---|---|
A | 01000001 | 00000000 01000001 | 01000001 |
中 | x | 01001110 00101101 | 11100100 10111000 10101101 |
从上面的表格还可以发现,UTF-8编码有一个额外的好处,就是ASCII编码实际上可以被看成是UTF-8编码的一部分,所以,大量只支持ASCII编码的历史遗留软件可以在UTF-8编码下继续工作。
所以现状是内存使用Unicode编码,硬盘使用UTF-8编码.
内存为什么不用UTF-8呢?
出现这个问题的原因是历史遗留问题,不同国家的硬盘中还躺了其他国家的代码,各个国家的代码的二进制还需要运行在计算机上使用,因此内存中必须使用Unicode的编码.
内存中还使用Unicode编码,是因为历史遗留问题造成的,但是因为现在写代码使用的都是UTF-8代码,所以以后内存中的代码都将变成UTF-8代码,并且以前遗留的各个国家的代码都将被淘汰,所以未来内存中使用的编码也将使用UTF-8编码替代Unicode编码。
乱码问题分析
- 文件从内存刷到硬盘的操作简称存文件
- 文件从硬盘读到内存的操作简称读文件
乱码的两种情况:
-
乱码一:存文件时选择了错误的编码格式
如:Mysql数据库没配置编码格式时默认使用拉丁编码,你往数据库插入汉字就会乱码,数据就丢失了(这是因为不同编码之间转换时,如果遇到转换失败的字节,会使用类似 ? 或 � 来代替,这样你再转换回去的时候,就不是原来的字节了)
乱码二:读文件时乱码
如:存文件时用utf-8编码,而读文件时选择了错误的解码方式,比如gbk,则在读阶段发生乱码,这时数据不会丢失选择正确的编码方式打开即可.