官术网_书友最值得收藏!

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文件,輸出結果如下:


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

主站蜘蛛池模板: 澄城县| 汝南县| 拜泉县| 顺昌县| 永宁县| 红桥区| 莆田市| 阳春市| 汤阴县| 孙吴县| 渝中区| 封丘县| 玉林市| 文登市| 宁乡县| 郎溪县| 常熟市| 瓦房店市| 吴江市| 兴业县| 彭山县| 临泉县| 根河市| 枣庄市| 江华| 广元市| 井冈山市| 乡宁县| 湖口县| 青川县| 班玛县| 赣榆县| 黄梅县| 曲水县| 敖汉旗| 内江市| 昆明市| 泸水县| 叶城县| 湾仔区| 依安县|