python encode 理解

基础知识

计算机只能处理0和1两个数字,所以所有的数据(文本、图像)必须变成0和1这样的数字。

ASCII编码

计算机是美国人发明的,所以最早只有127个字符被编写进计算机,也就是常见的阿拉伯数字,字母大小写,以及键盘上的符号。这被称为ASCII编码。比如A的ASCII编码为65,65再转换为01000001,这才是计算机处理的东西。

各个国家自己的编码

中国制定了GB2312编码,兼容ASCII编码,那么假设61,62,63在GB2312编码中对应的为慕课网三个字,在ASCII码表中对应的是A,B,C,在Shift_JIS(日本的编码)对应的是ハロー,那么中国的文本用GB2312编码,存储到计算机中为一串01数字,日本人使用Shift_JIS解码后,读到的就全是一串看不懂的日文乱码,甚至无法解析的二进制码。

Unicode编码

后来有了Unicode编码,它将全世界几乎所有的语言进行了汇总,使用了同一种编码,这样大家都使用同一种编码来进行编码、解码,就会最终得到正确的文字。

UTF-8编码

但是由于Unicode编码是使用16个数字位来进行的编码,太过占用资源,所以就有了UTF-8编码,这种编码使用8个数字位来进行存储,遇到中文会使用两个8位编码来存储。大大避免了浪费空间

计算机中的文字存储

所以记事本中的文字(如中文),使用Unicode来编码,存储到计算机中时,会再次被编码为UTF-8,在我们打开时,会先从UTF-8编码转为Unicode编码,再从Unicode编码转为各自国家的编码

网络之间的文字传输

服务器上的Unicode数据读取出来后,转为UTF-8编码(节省带宽),传输给浏览器,

Python3

Python3字符串默认使用Unicode编码所以Python3支持多国语言;

以Unicode表示的str通过encode()可以编码为指定的bytes

如果bytes使用了ASCII编码,遇到ASCII码表没有的字符会以\x##表示,此时使用'\x##'.decode('对应编码')解码即可

>>> import chardet
>>> str='中国a'

# utf-8编码
>>> str.encode('utf-8')
b'\xe4\xb8\xad\xe5\x9b\xbda'

>>> chardet.detect(str.encode('utf-8'))
{'encoding': 'utf-8', 'confidence': 0.7525, 'language': ''}

>>> str.encode('utf-8').decode('gbk')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'gbk' codec can't decode byte 0xad in position 2: illegal multibyte sequence

>>> str.encode('utf-8').decode('utf-8')
'中国a'

# gb2312 / gbk编码
>>> str.encode('gb2312')
b'\xd6\xd0\xb9\xfaa'

>>> str.encode('gbk')
b'\xd6\xd0\xb9\xfaa'
>>> chardet.detect('中国我爱你啊啊啊啊啊啊啊哈哈哈哈啊哈哈哈哈哈哈'.encode('gb2312'))
{'encoding': 'IBM855', 'confidence': 0.3697632002333717, 'language': 'Russian'}

>>> chardet.detect(str.encode('gbk'))
{'encoding': 'IBM855', 'confidence': 0.6143757788492946, 'language': 'Russian'}

# chardet识别仅在文字具有一定长度和一定复杂度时才可以识别正确
>>> chardet.detect('中国我爱你啊啊啊啊啊啊啊哈哈哈哈我是一只小小鸟'.encode('gb2312'))
{'encoding': 'GB2312', 'confidence': 0.7142857142857143, 'language': 'Chinese'}

>>> str.encode('gbk').decode('IBM855')
'ол╣Щa'

>>> str.encode('gbk').decode('utf-8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd6 in position 0: invalid continuation byte

>>> str.encode('gbk').decode('gbk')
'中国a'
posted @ 2017-12-13 21:53  yc紫日  阅读(936)  评论(0编辑  收藏  举报