昨天博客访问量超过20w了,很高兴,也希望这些笔记和文章能够真正帮到更多的人。对于一个做技术的人来说,分享真的会给自己带来很多快乐。不过说来也很惭愧,最近两个月都没写什么新的内容,一直忙于毕业设计和论文的事,也没学什么新的东西。不过想到马上要毕业将要踏上新的征程也是特别兴奋的。
关于字符串编码方面的内容很基础,学了很多次还是记不住,每次要用的时候又去查找相关资料,很麻烦,这里做一个总结记录一下,方便自己下一次查阅,也加深一下记忆(可能是撸多了,记忆力越来越差。。)。
编码
百度百科上对编码和解码的定义如下:编码是用预先规定的方法将文字、数字或其他对象转换成数码的过程。解码是编码的逆向。
这里我们不妨将人类可以很容易理解的消息作为“明文”,将人类不易懂但是更易于存储和传输的消息作为“密文”。那么编码和解码的关系如下:
因为计算机只能识别0和1,我们人类易于理解的那些符号数字没办法直接存储到计算机中,必须先将这些符号按照事先规定的方式编码成0/1串才能存储到计算机或者通过网络进行传输。当我们从硬盘或者网络中读取文件时,我们读取到的内容全是0/1串,需要将这些内容按照一定的方式解码成我们易于理解的明文,然后才能查看或进行相关的处理。
编码有一个必要条件是编码的过程不能丢失任何信息,我们能够从密文解码出和原文完全一样的内容。
编码方式
将明文编码成密文需要按照一定的编码方式,编码方式多种多样,分别对应于不同的字符集。
ASCII
上个世纪60年代,美国制定了一套字符编码,对英语字符与二进制位之间的关系,做了统一规定。这被称为ASCII码,一直沿用至今。
ASCII码一共规定了128个字符的编码,比如空格”SPACE”是32(二进制00100000),大写的字母A是65(二进制01000001)。这128个符号(包括32个不能打印出来的控制符号),只占用了一个字节的后面7位,最前面的1位统一规定为0。
其他编码
对于英语来说128个字符就已经够用了,但是对于其他语言来说却不够。因此针对不同的语言先后出现了多种编码方式,例如针对中文的GB2312和GBK编码,针对中文繁体的Big5编码等等,这些编码方式都使用多个字节表示一个字符。
Unicode
随着越来越多的编码方式的出现,急需一种能够包含全世界所有符号的编码系统来消灭乱码,这种编码系统就叫做Unicode。Unicode只是一套编码系统,包含所有字符集,却并不规定编码后的二进制代码如何存储。
UTF-32使用4个字节存储每一个字符,但是对于英文字符来说,使用ASCII编码只需1个字节即可存储,这极大的浪费了存储空间。
因此出现了一种变长的编码方式UTF-8,UTF-8是使用得最广泛的Unicode编码实现方式,使用1-4个字节表示一个字符,根据不同的字符变化长度。比如对于英文字符,1个字节就够了,但是对于中文,可能需要2-4个字节才能存储。
Base64
Base64是网络上最常见的用于传输8Bit字节代码的编码方式,可用于在HTTP环境下传递较长的标识信息。采用Base64编码具有不可读性,可用作简单的加密方式。
Python 3编码
以前用Python 2,每次使用中文就会碰到各种编码问题,但是Python 3使得字符串编码变得非常简单。
我们可以通过以下代码查看Python 3的字符串默认编码:
import sys
sys.getdefaultencoding()
Python 3的默认编码方式是UTF-8。
使用Python解释器进行如下编码解码操作,在bytes和str之间转换:
>>> '中'.encode()
b'\xe4\xb8\xad'
>>> b'\xe4\xb8\xad'.decode('utf-8')
'中'
我们在使用Python以二进制的形式写入文件时,需要先将字符串编码成字节串,然后再写入文件。以二进制的形式读取文件时也是如此,需要将读取的字节串解码成字符串。
参考文档:
1. 字符编码笔记:ASCII,Unicode和UTF-8
2. Python 3的bytes/str之别
3. Python3的编码问题