binascii 模块是 Python 中一个非常重要且常用的模块,它的名字来源于 "binary" 和 "ASCII",它的核心功能是在二进制数据(字节串)和各种 ASCII 编码的文本表示(如十六进制、Base64)之间进行转换。

当你需要处理二进制数据,但又想以文本形式(比如在日志中、URL里、或者配置文件里)存储或传输它时,binascii 就派上用场了。
为什么需要 binascii?
想象一个场景:你有一个文件,比如一张图片 image.png是纯粹的二进制数据,包含了像素信息、颜色表等,如果你尝试直接读取这些二进制数据并将其打印出来,你会看到一堆乱码和不可见的控制字符,因为它们不是为人类阅读设计的。
为了解决这个问题,我们可以将这些二进制数据转换成一种文本格式,
- 十六进制:每 4 位二进制转换成一个 0-9, a-f 的字符,非常直观。
- Base64:一种使用 64 个常用字符来表示任意二进制数据的方法,广泛用于在文本协议(如 Email、JSON)中传输二进制附件。
binascii 模块就是专门用来高效地完成这些转换工作的。

核心功能与常用函数
binascii 模块提供了两组功能相似但接口不同的函数:
- 以
a2b_(ASCII to Binary) 和b2a_(Binary to ASCII) 开头的函数:它们处理的是字节串 (bytes) 和字节串 (bytes) 之间的转换,这是最常用、最推荐的方式。 - 以
a2b_和b2a_开头,但名称中包含_hex或_base64的函数:它们处理的是字节串 (bytes) 和字符串 (str) 之间的转换,这些函数在 Python 2 中更常见,但在 Python 3 中也能使用,不过需要注意编码问题。
下面我们重点介绍第一组,也就是现代 Python 开发中推荐使用的函数。
十六进制 编码与解码
这是最常用的转换之一。
binascii.b2a_hex(data)
- 功能:将二进制数据编码为十六进制表示。
- 参数:
data(bytes) - 要编码的二进制数据。 - 返回值:
bytes- 包含小写十六进制字符的字节串。 - 别名:
hexlify
binascii.a2b_hex(hexstr)
- 功能:将十六进制表示解码为二进制数据。
- 参数:
hexstr(bytes) - 包含十六进制字符的字节串。 - 别名:
unhexlify
示例:
import binascii
# 原始二进制数据
original_data = b"Hello, World!"
# 1. 编码为十六进制
hex_data = binascii.b2a_hex(original_data)
print(f"原始数据: {original_data}")
print(f"编码后的十六进制 (bytes): {hex_data}")
print(f"解码后的字符串: {hex_data.decode('ascii')}") # 假设我们知道它是ASCII
# 2. 从十六进制解码回二进制
decoded_data = binascii.a2b_hex(hex_data)
print(f"解码回的二进制数据: {decoded_data}")
print(f"解码后的数据与原始数据是否相同: {decoded_data == original_data}")
# 也可以使用别名
hex_data_alias = binascii.hexlify(original_data)
decoded_data_alias = binascii.unhexlify(hex_data_alias)
print(f"使用别名编码: {hex_data_alias}")
print(f"使用别名解码: {decoded_data_alias}")
输出:
原始数据: b'Hello, World!'
编码后的十六进制 (bytes): b'48656c6c6f2c20576f726c6421'
解码后的字符串: 48656c6c6f2c20576f726c6421
解码回的二进制数据: b'Hello, World!'
解码后的数据与原始数据是否相同: True
使用别名编码: b'48656c6c6f2c20576f726c6421'
使用别名解码: b'Hello, World!'
Base64 编码与解码
Base64 在网络传输中非常常见,例如在邮件附件、JWT 令牌、图片的 Data URI 中。
binascii.b2a_base64(data, *, newline=True)
- 功能:将二进制数据编码为 Base64 格式。
- 参数:
data(bytes): 要编码的二进制数据。newline(bool): 是否在输出末尾添加换行符\n,默认为True,这符合 RFC 标准。
- 返回值:
bytes- 包含 Base64 编码数据的字节串,末尾可能有一个换行符。
binascii.a2b_base64(data)
- 功能:将 Base64 编码的数据解码为二进制数据。
- 参数:
data(bytes) - 包含 Base64 编码数据的字节串,可以包含换行符。 - 返回值:
bytes- 解码后的原始二进制数据。
示例:
import binascii
# 原始二进制数据
original_data = b"Python's binascii module is powerful."
# 1. 编码为 Base64
b64_data = binascii.b2a_base64(original_data, newline=False) # 去掉末尾的换行符
print(f"原始数据: {original_data}")
print(f"编码后的 Base64 (bytes): {b64_data}")
# 2. 从 Base64 解码回二进制
decoded_data = binascii.a2b_base64(b64_data)
print(f"解码回的二进制数据: {decoded_data}")
print(f"解码后的数据与原始数据是否相同: {decoded_data == original_data}")
# 如果包含换行符,a2b_base64 也能正确处理
b64_data_with_newline = binascii.b2a_base64(original_data)
decoded_data_with_newline = binascii.a2b_base64(b64_data_with_newline)
print(f"带换行符的解码结果: {decoded_data_with_newline}")
输出:
原始数据: b"Python's binascii module is powerful."
编码后的 Base64 (bytes): b'UHl0aG9uJ3MgYmluc2Fzc2UgbW9kdWxlIGlzIHBvdXI/ZnJvbmcu'
解码回的二进制数据: b"Python's binascii module is powerful."
解码后的数据与原始数据是否相同: True
带换行符的解码结果: b"Python's binascii module is powerful."
CRC 校验
binascii 还可以用来计算循环冗余校验,这是一种常用的校验数据完整性的方法。
binascii.crc32(data)
- 功能:计算数据的 CRC32 校验和。
- 参数:
data(bytes) - 要计算校验和的二进制数据。 - 返回值:
int- 一个 32 位的整数,表示校验和,这个值可能是一个负数,你可以使用& 0xffffffff将其转换为无符号整数。
示例:
import binascii
data = b"Hello, World!"
checksum = binascii.crc32(data)
print(f"数据: {data}")
print(f"CRC32 校验和 (有符号): {checksum}")
print(f"CRC32 校验和 (无符号): {checksum & 0xffffffff}")
# 修改数据中的一个字节,校验和会完全不同
data_modified = b"Hello, World?" # ! 变成了 ?
checksum_modified = binascii.crc32(data_modified)
print(f"修改后的数据: {data_modified}")
print(f"修改后的 CRC32 校验和: {checksum_modified & 0xffffffff}")
输出:
数据: b'Hello, World!'
CRC32 校验和 (有符号): -1826328476
CRC32 校验和 (无符号): 3089625236
修改后的数据: b'Hello, World?'
修改后的 CRC32 校验和: 2206341478
binascii 与 base64、hashlib 等模块的关系
Python 的标准库中还有其他模块也提供类似功能,binascii 和它们的关系如下:
| 功能 | binascii 模块 |
base64 模块 |
hashlib 模块 |
|---|---|---|---|
| Base64 编码/解码 | b2a_base64, a2b_base64 |
b64encode, b64decode |
不提供 |
| Hex 编码/解码 | b2a_hex, a2b_hex |
b16encode, b16decode |
不提供 |
| CRC 校验 | crc32, crc_hqx |
不提供 | 不提供 |
| 哈希摘要 | 不提供 | 不提供 | md5, sha1, sha256 等 |
binascii:核心是 二进制与文本编码的转换,它非常高效,因为它通常是用 C 实现的,它的 CRC 功能是独一无二的。base64:专注于 Base64 的编码和解码,它的 API 更现代(直接返回bytes),有时比binascii的对应函数更方便。hashlib:专注于 哈希算法(MD5, SHA 等),用于生成数据的“指纹”或摘要,用于校验完整性和加密,而不是为了数据表示。
如何选择?
- 如果只是简单的 Hex 或 Base64 转换,
binascii和base64都可以。base64的 API 可能更简洁一些。 - 如果需要计算 CRC 校验和,必须使用
binascii。 - 如果需要计算 MD5, SHA 等哈希值,必须使用
hashlib。
实战应用场景
简单的文件哈希校验
虽然 hashlib 更适合,但 binascii 可以用来展示校验和的原理。
import binascii
def calculate_file_crc(filepath):
"""计算文件的 CRC32 校验和"""
with open(filepath, 'rb') as f:
file_data = f.read()
return binascii.crc32(file_data)
# 假设你有一个名为 'my_image.png' 的文件
# checksum = calculate_file_crc('my_image.png')
# print(f"File checksum: {checksum & 0xffffffff}")
在 JSON 中传输二进制数据
JSON 标准不支持二进制数据,一个常见的解决方案是先将二进制数据用 Base64 编码,然后以字符串的形式存入 JSON。
import binascii
import json
# 1. 原始二进制数据
binary_data = b"{'key': 'value', 'data': [1, 2, 3]}"
# 2. 使用 binascii 编码为 Base64
b64_encoded_data = binascii.b2a_base64(binary_data, newline=False).decode('ascii')
# 3. 构造 JSON 对象
payload = {
"filename": "config.dat",
"content_type": "application/octet-stream",
"data": b64_encoded_data # Base64 字符串
}
# 4. 序列化为 JSON 字符串
json_string = json.dumps(payload)
print("JSON to be sent:")
print(json_string)
# 5. 接收方解析 JSON 并解码
received_payload = json.loads(json_string)
received_b64_data = received_payload['data']
# 6. 使用 binascii 解码回二进制
decoded_binary_data = binascii.a2b_base64(received_b64_data.encode('ascii'))
print("\nDecoded binary data:")
print(decoded_binary_data)
print(f"Is original data equal? {decoded_binary_data == binary_data}")
注意事项
- Python 3 的
bytesvsstr:在 Python 3 中,binascii的核心函数都严格地在bytes类型上工作,不要尝试将str(Unicode 字符串) 直接传给它们,除非你明确知道它的编码并已经用.encode()转换过了。 - 错误处理:如果传入的
hexstr或b64_data包含非法字符,a2b_hex和a2b_base64会抛出binascii.Error异常,建议使用try...except来捕获这个异常。try: bad_hex = binascii.a2b_hex(b'ghijkl') # g, h 不是合法的十六进制字符 except binascii.Error as e: print(f"解码失败: {e}")
binascii 是 Python 中处理二进制数据与文本格式之间转换的基石,虽然 base64 等模块在某些方面提供了更现代的接口,但 binascii 凭借其高效性和独特的 CRC 功能,在 Python 开发工具箱中占据着不可或缺的地位,当你需要处理 Hex、Base64 编码或进行简单的数据校验时,binascii 应是你的首选之一。
