购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

| 1.5 |

字节到大整数的打包与解包

在实际应用中,我们有时需要将一个字节字符串解压成一个整数,或将一个大整数转换为一个字节字符串。

例如,要处理一个拥有16个128位长的元素的字节字符串,示例如下:


data = b'\x00\x124V\x00x\x90\xab\x00\xcd\xef\x01\x00#\x004'

为了将字节字符串解析为整数,使用int.from_bytes()方法指定字节顺序:


print(f'data len is: {len(data)}')
print(int.from_bytes(data, 'little'))
print(int.from_bytes(data, 'big'))

执行py文件,输出结果如下:


data len is: 16
69120565665751139577663547927094891008
94522842520747284487117727783387188

为了将一个大整数转换为字节字符串,可使用int.to_bytes()方法指定字节数和字节顺序,代码(pack_unpack.py)示例如下:


x = 94522842520747284487117727783387188
print(x.to_bytes(16, 'big'))
print(x.to_bytes(16, 'little'))

执行py文件,输出结果如下:


b'\x00\x124V\x00x\x90\xab\x00\xcd\xef\x01\x00#\x004'
b'4\x00#\x00\x01\xef\xcd\x00\xab\x90x\x00V4\x12\x00'

大整数和字节字符串之间的转换操作并不常见,仅在一些应用领域出现,比如密码学或者网络。如IPv6网络地址使用一个128位的整数表示。作为上述操作的一种替代方案,我们可能想使用struct模块来解压字节。这样也行得通,不过利用struct模块来解压字节对于整数的大小是有限制的。因此,我们可能想解压多个字节串并将结果合并为最终的结果,相关代码(pack_unpack.py)示例如下:


import struct
hi, lo = struct.unpack('>QQ', data)
print(hi, lo)
print((hi << 64) + lo)

执行py文件,输出结果如下:


5124093560524971 57965157801984052
94522842520747284487117727783387188

字节顺序规则(little或big)仅仅指定了构建整数时字节的低位和高位排列方式,相关代码(pack_unpack.py)示例如下:


x = 0x01020304
print(x.to_bytes(4, 'big'))
print(x.to_bytes(4, 'little'))

执行py文件,输出结果如下:


b'\x01\x02\x03\x04'
b'\x04\x03\x02\x01'

如果试着将一个整数打包为字节字符串,会得到错误结果。如果需要的话,可以使用int.bit_length()方法来决定需要多少字节位存储这个值,相关代码(pack_unpack.py)示例如下:


x = 523 ** 23
print(x)
print(x.bit_length())
nbytes, rem = divmod(x.bit_length(), 8)
if rem:
    nbytes += 1

print(x.to_bytes(nbytes, 'little'))
print(x.to_bytes(16, 'little'))

执行py文件,输出结果如下: PLQNpHbzlSBgfTEvzG8op/VmbNswgXRq6hpAHVJDTa/Jabgd7x1aQ9NAIV/X2fLq


335381300113661875107536852714019056160355655333978849017944067
208
b'\x03X\xf1\x82iT\x96\xac\xc7c\x16\xf3\xb9\xcf\x18\xee\xec\x91\xd1\x98\xa2\xc8\xd9R\xb5\xd0'
OverflowError: int too big to convert

点击中间区域
呼出菜单
上一章
目录
下一章
×