二进制数据
本篇内容主要介绍二进制数据的编解码问题,涉及的模块有 base64、struct、chardet。
base64
base64
模块主要提供将二进制数据编码为可打印的 ASCII 字符以及将这些编码解码回二进制数据的函数。本篇主要介绍模块中的两个函数 b64encode()
和 b64decode()
。
b64encode() 和 b64decode()
>>> import base64
# 编码
>>> s = b'hello world'
>>> base64.b64encode(s)
b'aGVsbG8gd29ybGQ='
# 解码
>>> s1 = b'aGVsbG8gd29ybGQ='
>>> base64.b64decode(s1)
b'hello world'
b64encode()
的作用是对 bytes-like object
进行 Base64
编码,并返回编码后的 bytes
;b64decode()
的作用是解码经 Base64
编码过的 bytes-like object
或者 ASCII 字符串,并返回解码过的 bytes
。
更多关于 base64
模块的详细信息,可参考:
https://docs.python.org/3.8/library/base64.html
struct
struct
模块,可以执行 Python 值和以 Python bytes
对象表示的 C 结构之间的转换。这可以用来处理存储在文件中或者是从网络等其他来源获取的二进制文件。接下来主要介绍 pack()
和 unpack()
两个函数的使用方法.
pack() 和 unpack()
>>> from struct import Struct
>>> record_struct = Struct('>hhl')
>>> record_struct.pack(1,2,3)
b'\x00\x01\x00\x02\x00\x00\x00\x03'
>>> record_struct.unpack(b'\x00\x01\x00\x02\x00\x00\x00\x03')
(1, 2, 3)
pack
函数是把数据类型变为 bytes
,而 unpack
是将 bytes
变为相应的数据类型。
这里通过创建实例 Struct
,指定一个格式 >hhl
,这里 >
表示 big-endian
大端模式,也就是将高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。h
表示对应 2 字节带符号整数,对应 C 的 short
类型;l
代表 4 字节带符号整数,对应 C 的 long
类型。
关于 struct
模块定义的数据类型可以参考 Python 的官方文档:
https://docs.python.org/3/library/struct.html#format-strings
https://docs.python.org/3/library/struct.html#format-characters
pack()
和 unpack()
操作能够以模块级别的函数被调用,示例如下:
>>> from struct import *
>>> pack('hhl', 1, 2, 3)
b'\x01\x00\x02\x00\x03\x00\x00\x00'
>>> unpack('hhl', b'\x01\x00\x02\x00\x03\x00\x00\x00')
(1, 2, 3)
这样的操作,在代码同样结构出现多个地方的时候,需要多次书写格式。建议创建 Struct
实例,指定格式代码后所有操作集中处理。这样也能够更简单地维护代码。
chardet
chardet
是一个第三方库,是一个通用字符编码检测器。顾名思义,即是用以检测编码。
安装 chardet
使用 chardet
需要安装(若是安装了 Anaconda,可以跳过),使用如下命令:
$ pip install chardet
使用 chardet
举例说明,如何使用 chardet 进行编码检测。示例代码如下:
>>> import chardet
>>> chardet.detect(b'Hello world!')
{'encoding': 'ascii', 'confidence': 1.0, 'language': ''}
检测出的编码是 ascii,这里有个参数 confidence,这里的 1.0(即是 100% ) 表示检测的概率。
尝试检测 GBK 编码的中文:
>>> data = "黄河西来决昆仑,咆哮万里触龙门".encode('gbk')
>>> chardet.detect(data)
{'encoding': 'GB2312', 'confidence': 0.99, 'language': 'Chinese'}
检测的编码是 GB2312,注意到 GBK 是 GB2312 的超集,两者是同一种编码,检测的概率是 99%,language 字段指出的语言是 Chinese。
可尝试对日文进行检测:
>>> data = 'いちだい さんぜん だいせん せかい'.encode('euc-jp')
>>> chardet.detect(data)
{'encoding': 'EUC-JP', 'confidence': 0.99, 'language': 'Japanese'}
使用 chardet
模块进行编码检测,能够有效获取编码进行转换,方便后续的使用。
下面的链接罗列了 chardet
支持的编码列表:
https://chardet.readthedocs.io/en/latest/supported-encodings.html
参考资料
来源
- David M. Beazley;Brian K. Jones.Python Cookbook, 3rd Edtioni.O’Reilly Media.2013.
- Luciano Ramalho.Fluent Python.O'Reilly Media.2015
- “base64 — Base16, Base32, Base64, Base85 Data Encodings”.docs.python.org.Retrieved 26 January 2020
- “struct — Interpret bytes as packed binary data”.docs.python.org.Retrieved 26 January 2020
- "Usage".chardet.readthedocs.io.Retrieved 28 January 2020
- "Supported encodings".chardet.readthedocs.io.Retrieved 28 January 2020
- 廖雪峰.“Python 教程”.liaoxuefeng.com.[2020-01-28].
以上就是本篇的主要内容
欢迎关注微信公众号《书所集录》