python 二进制字符串与十六进制字符串转换

在 Python 中,通过 data.hex() 将二进制字节串(bytes)转换为十六进制字符串后,可以使用 bytes.fromhex() 方法将十六进制字符串还原为原始的二进制字节串。以下是详细步骤和示例:

原理

  • data.hex():将 bytes 对象转换为十六进制字符串,每个字节变成两个十六进制字符(无 0x 前缀)。

  • bytes.fromhex():将十六进制字符串(可以包含空格或不含空格)转换回 bytes 对象。

示例代码

假设你有一个二进制字节串,经过 hex() 转换为十六进制字符串,然后想还原回去:

python

# 原始二进制数据
data = b'05\x02\x01\x01\x04\x06'

# 转换为十六进制字符串
hex_str = data.hex()
print(f"Hex string: {hex_str}")  # 输出: 050201010406

# 从十六进制字符串还原为二进制字节串
restored_data = bytes.fromhex(hex_str)
print(f"Restored bytes: {restored_data}")  # 输出: b'05\x02\x01\x01\x04\x06'

# 验证是否一致
print(f"Original == Restored: {data == restored_data}")  # 输出: True

完整流程:写入文件后读取并还原

如果你将十六进制字符串保存到文件,然后读取并还原为二进制字节串,可以这样做:

python

# 原始二进制数据
sample_data = [
    b'05\x02\x01\x01\x04\x06',
    b'x0f+\x06\x01\x02\x01\x03\x01\x01\x01\x02\x01'
]

# 转换为十六进制字符串并写入文件
with open('hex_data.txt', 'w') as f:
    for line in sample_data:
        hex_str = line.hex()
        f.write(hex_str + '\n')

# 从文件读取十六进制字符串并还原为二进制
with open('hex_data.txt', 'r') as f:
    for line in f:
        hex_str = line.strip()  # 去掉换行符
        restored_bytes = bytes.fromhex(hex_str)
        print(f"Restored bytes: {restored_bytes}")

输出:

Restored bytes: b'05\x02\x01\x01\x04\x06'
Restored bytes: b'x0f+\x06\x01\x02\x01\x03\x01\x01\x01\x02\x01'

注意事项

  1. bytes.fromhex() 的输入要求:

    • 输入必须是有效的十六进制字符串(字符只能是 0-9 和 a-f 或 A-F)。

    • 可以包含空格(例如 '05 02 01'),bytes.fromhex() 会忽略这些空格。

    • 如果字符串中有无效字符,会抛出 ValueError。

    示例:

    python

    bytes.fromhex('0502 0101 0406')  # 有效,空格被忽略
    # 输出: b'05\x02\x01\x01\x04\x06'
  2. 错误处理: 如果你的十六进制字符串可能有问题,可以添加异常处理:

    python

    hex_str = '05020101g406'  # 包含无效字符 'g'
    try:
        restored_data = bytes.fromhex(hex_str)
    except ValueError as e:
        print(f"Error: {e}")  # 输出: Error: invalid hex string
  3. 与文件操作结合:

    • 如果你的十六进制字符串来自文本文件,确保去掉多余的换行符或空白(用 strip())。

    • 如果直接保存的是二进制数据而非十六进制字符串,则应以 'rb' 模式读取,不需要 bytes.fromhex()。


总结

  • 从二进制到十六进制:data.hex()

  • 从十六进制到二进制:bytes.fromhex(hex_str)

  • 这两个方法是一对互逆操作,可以无损地转换数据。

如果你有更复杂的场景(比如十六进制字符串格式不同,或需要处理大文件),请告诉我,我可以进一步优化代码!

你可能感兴趣的:(python)