最稳妥方法是用 binascii 模块:以 rb 模式读二进制文件,用 binascii.hexlify() 转小写十六进制字符串,大写加 .upper(),分隔符用 b2a_hex(sep=);还原时用 unhexlify() 并确保输入合法,写入用 wb 模式。

直接用 binascii 模块最稳妥,别自己写循环拼接或用 hex() 方法处理非 bytes 对象——那会出错。
读取二进制文件并转为十六进制字符串
关键在「以 rb 模式打开」+「用 binascii.hexlify() 处理 bytes」。如果误用 str.encode().hex() 或对已解码的文本调用 hex(),会得到错误结果。
with open("data.bin", "rb") as f: raw = f.read()-
hex_str = binascii.hexlify(raw).decode("ascii")—— 返回小写十六进制字符串,如"a1b2c3" - 若需大写,加
.upper():binascii.hexlify(raw).decode("ascii").upper() - 想带空格或分隔符?别用
hexlify后手动切片,改用binascii.b2a_hex(raw, sep=" ", bytes_per_sep=1)(Python 3.8+)
将十六进制字符串还原为二进制文件
必须确保输入是合法十六进制字符串(长度为偶数、只含 0-9a-fA-F),否则 binascii.unhexlify() 抛 binascii.Error: Non-hexadecimal digit found。
-
raw_bytes = binascii.unhexlify("a1b2c3")—— 输入可为 str 或 bytes,但不能带0x前缀 - 若字符串含前缀或空格,先清理:
hex_str.replace("0x", "").replace(" ", "") - 写入文件时务必用
wb模式:with open("out.bin", "wb") as f: f.write(raw_bytes) - 注意:
bytes.fromhex("a1b2c3")是等效替代,但不校验非法字符(遇到非 hex 字符直接报ValueError,不如unhexlify的错误信息明确)
内存中 bytes 与 hex 字符串互转的边界情况
不要对 str 类型对象直接调用 .hex(),那是 bytes 和 bytearray 的方法。常见翻车点:
立即学习“Python免费学习笔记(深入)”;
-
"a1b2".hex()→AttributeError;正确是bytes.fromhex("a1b2")或binascii.unhexlify("a1b2") -
b"\x00\xff".hex()返回"00ff",但b"\x00\xff".hex(":")(Python 3.8+)才支持分隔符 - 性能上,
binascii.hexlify()比bytes.hex()略快(尤其大数据量),但差距通常可忽略 - 兼容性:
bytes.hex()是 Python 3.5+ 引入,旧环境必须用binascii
真正容易被忽略的是编码隐式转换——比如从网络接收的 hex 字符串可能是 UTF-8 编码的 bytes,得先 .decode("utf-8") 再传给 unhexlify,漏这步会直接报错。


















