编码 -- python2

机器码到字符(中文字符、英文字符...)的转换关系

ASCII

  • ASCII(American Standard Code for Information Interchange)单字节编码,而单字节可以表示256个不同的字符,但是ASCII只用了一半,即0-127,(\x80一下)

MBCS(multiple byte character set):多字节字符集

  • 因为ASCII编码只用到了\x80以下,并且不能表示中文,所以引入了一种编码机制,如果一个字节是\x80以下,使用ASCII编码。但是如果在\x80及其以上,就配合第二个字节合起来表示一个字符(至少两个字节)

  • 这时,IBM创造一个Code Page的东西,来存放所有国家的编码(就是个统一的编码表),中国的GBK在第936页,所以页可以用CP936表示GBK
    微软的ASNI就是MBCS,根据默认区域来设置默认的编码

  • MBCS是这些编码的统称,也可以称为DBCS(double byte character set),因为基本上都使用两个字节

Unicode

融合所有编码、统一编码

  • UCS-2,两个字节(256*256)表示一个字符,后面发现会出现2个字节也有点不够,就引入UCS-4,四个字节表示一个字符,但是通常还是使用UCS-2

UCS(Unicode Charater Set),是一张编码表,字符如果传输、存储由UTF(UCS Transformation Format)来负责
所以,最开始直接使用UCS的码位来保存,这就是UTF-16,比如,"汉"直接使用\x6C\x49保存(UTF-16-BE),或是倒过来使用\x49\x6C保存(UTF-16-LE)。

  • 如果大家遵循这个标准的话,美国人不乐意了,因为他们日常编码(机器码-->英文字符)只需要一字节就够了,但是大家都用的话,美国人不用就会被局限,所以他们也得用,用的话就会造成多余的内存消耗 ...于是UTF-8现世(变长的Unicode编码)

前提知识:当你打开一个文件的时候,你首先需要指定编码方式,然后系统会根据指定的编码来解码文件内容。之所以我们没有遇见,是因为系统会帮我们默认一种编码
打开notepad.exe-->点击文件-->打开

编码 -- python2
GIF.gif

如果默认使用UTF-8编码保存数据,则会在文件加上BOM头
BOM_UTF8 '\xef\xbb\xbf'
BOM_UTF16_LE '\xff\xfe'
BOM_UTF16_BE '\xfe\xff'

  • BOM(Byte Order Mark),字节顺序标记,用来指定编码方式的。

举个栗子:为什么记事本保存'姹塧'后,打开文件会显示'汉a'?

1、首先明确我们的区域默认是GBK(也可以是:CP936),也就是ANSI使用的这个代码页编码


编码 -- python2
2018-09-30_102324.png

编码 -- python2
cmd命令行属性的选项列表

2、另存为ANSI编码的文件。


编码 -- python2
2018-09-30_102812.png

3、保存文件内容时,使用GBK(CP936)编码保存,输出显示使用GBK解码,没问题,正常解码(输出的内容默认是decode("GBK"),也就是去CP936页找到具体的中文字符来显示)


编码 -- python2
2018-09-30_103315.png

前提条件:微软虽然保存使用ANSI(中文版windows是:CP936)来保存,但是当他的记事本解码时,默认先用UTF-8测试,看是否可以使用UTF-8解码成功,如果成功就返回

就是这种解码策略,造成的这个bug

将gbk编码后的内容,使用"utf-8"解码,刚好是"汉a"的utf-8编码的内容


编码 -- python2
2018-09-30_104743.png
  • 小结各国文字就是一种字符,使用不同的编码表,就转化成了不同长度的十六进制数

python2.x编码问题

python中有str类型,其实是字节串,是中文字符查询Unicode码表(编码)后的,再经过区域编码(中国是CP936)转换后的内容,这里我们就把字符串对应的Unicode码表后的内容理解为真正的字符串,str类型是区域编码后的内容

https://www.cnblogs.com/huxi/archive/2010/12/05/1897271.html