几种编码方式的总结

之前总是会遇到编码的问题,一直处于半懂不懂的状态,这次来对几种编码方式简单的进行梳理一下。

首先介绍字符的编码方式

ASCII码
首先需要清楚的是ASCII码主要是用来显示英语和部分西欧语言的编码系统。标准的ARCII码使用7位二进制数表示所有的大小写字母、数字、标点符号及特殊字符,剩下的一位规定为0。

非ASCII码
英文字符用7个二进制位就可以完全表示,而对其它语言而言7个二进制位是不够的,所以,一些国家使用剩下的一个二进制位也用来表示字符,这样一共有256个符号。但即使数量上满足,对于不同的语言,编码表示的字符也是不一样的。除此之外,还有例如中文这种具有许多字符的语言,用一个字节是无法完全表示的,所以需要多个字节表示。例如中文常见的编码方式GB2312就是使用两个字节表示一个字符。

Unicode
世界上存在着许多的编码方式,编码方式的多样性使得经常会出现乱码的问题,就是由于编码与读取使用不同的编码方式。针对这个问题,Unicode编码出现了,它是将世界所有的符号编码,给他一个独一无二的编号。
Unicode只是一个符号集,它只规定了符号的二进制代码,没有规定二进制代码如何存储。有的字符需要三四个字节表示,这时ASCII码与Unicode如何分别将是一个问题。而且若字符都用四个字节表示,对于只需要一个字节的英文字符而言,会造成极大的存储浪费。

UTF-8
UTF-8是Unicode编码的一个实现方式,类似的还有UTF-16和UTF-32。UTF-8是一种变长编码方式。
1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。
2)对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。

文件的编码格式与编码声明
我们经常在文件开头看见 # coding=utf-8等声明,那么这个究竟是什么意思,这个与文件本身的编码又是什么关系。

以notepad++为例,在格式选项可以为文件设置编码方式,有ANSI、UTF-8及UTF-8的无BOM格式等。它决定了该源文件中字符串的编码格式。而文件开头#!coding=utf-8或者#!coding=gbk是给python的解释器看的。当声明#!coding=utf-8时,在notepad++中所有编码为gbk的文件打开后在显示是都被转换到utf-8的编码,但是退出的时候还是还原到gbk。

我们看下面这个例子。

#!coding=utf-8

s=str('你好')
print(s)
print('s:%s' % s)

此示例使用的是gbk编码方式,运行结果如下所示:

UnicodeDecodeError: 'utf8' codec can't decode byte 0xb9 in
position 0: unexpected code byte

整个运行过程:
1. 因为文件编码是GBK,得到的是’你好’的GBK编码,将它转换成 unicode的时候,会用UTF8进行解码,而大家查utf-8的编码表会发现,它在utf8编码表中根本不存在,所以会报上述错误。

我们再看下一个例子。

#!coding=gbk

s=str('你好')
print(s)
print('s:%s' % s)

文件使用utf-8编码方式,程序的输出如下图。整个过程:
1. 获取’你好’的编码:由文件编码格式确定(即utf-8编码形式)。
2. 转成 unicode编码的时候,在这个转换的过程中,对于步骤一获取的编码的解码,不是用utf-8解码,而是用声明编码处指定的编码GBK,解码后得到就是图片所示。
这里写图片描述

所以很多的乱码问题就是由于notepad++中声明的编码与实际编码不一致,因此最好是能够统一编码。

猜你喜欢

转载自blog.csdn.net/dxk_093812/article/details/81321543