3.5 字节到大整数的打包与解包
假设你的程序需要处理一个拥有128位长的16个元素的字节字符串。比如:
为了将bytes解析为整数,使用 方法,并像下面这样指定字节顺序:
- >>> len(data)
- 16
- >>> int.from_bytes(data, 'little')
- 69120565665751139577663547927094891008
- >>> int.from_bytes(data, 'big')
- 94522842520747284487117727783387188
- >>>
大整数和字节字符串之间的转换操作并不常见。然而,在一些应用领域有时候也会出现,比如密码学或者网络。例如,IPv6网络地址使用一个128位的整数表示。如果你要从一个数据记录中提取这样的值的时候,你就会面对这样的问题。
作为一种替代方案,你可能想使用6.11小节中所介绍的 模块来解压字节。这样也行得通,不过利用 模块来解压对于整数的大小是有限制的。因此,你可能想解压多个字节串并将结果合并为最终的结果,就像下面这样:
- b'\x00\x124V\x00x\x90\xab\x00\xcd\xef\x01\x00#\x004'
- >>> import struct
- >>> hi, lo = struct.unpack('>QQ', data)
- >>> (hi << 64) + lo
- 94522842520747284487117727783387188
- >>>
如果你试着将一个整数打包为字节字符串,那么它就不合适了,你会得到一个错误。如果需要的话,你可以使用 方法来决定需要多少字节位来存储这个值。
- >>> x = 523 ** 23
- >>> x
- 335381300113661875107536852714019056160355655333978849017944067
- >>> x.to_bytes(16, 'little')
- File "<stdin>", line 1, in <module>
- OverflowError: int too big to convert
- >>> x.bit_length()
- 208
- >>> nbytes, rem = divmod(x.bit_length(), 8)
- >>> if rem:
- ... nbytes += 1
- ...
- >>>
- >>> x.to_bytes(nbytes, 'little')
- >>>
原文: