W3Cschool
恭喜您成為首批注冊(cè)用戶(hù)
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
你有一個(gè)字節(jié)字符串并想將它解壓成一個(gè)整數(shù)。或者,你需要將一個(gè)大整數(shù)轉(zhuǎn)換為一個(gè)字節(jié)字符串。
假設(shè)你的程序需要處理一個(gè)擁有128位長(zhǎng)的16個(gè)元素的字節(jié)字符串。比如:
data = b'\x00\x124V\x00x\x90\xab\x00\xcd\xef\x01\x00#\x004'
為了將bytes解析為整數(shù),使用 int.from_bytes()
方法,并像下面這樣指定字節(jié)順序:
>>> len(data)
16
>>> int.from_bytes(data, 'little')
69120565665751139577663547927094891008
>>> int.from_bytes(data, 'big')
94522842520747284487117727783387188
>>>
為了將一個(gè)大整數(shù)轉(zhuǎn)換為一個(gè)字節(jié)字符串,使用 int.to_bytes()
方法,并像下面這樣指定字節(jié)數(shù)和字節(jié)順序:
>>> x = 94522842520747284487117727783387188
>>> x.to_bytes(16, 'big')
b'\x00\x124V\x00x\x90\xab\x00\xcd\xef\x01\x00#\x004'
>>> x.to_bytes(16, 'little')
b'4\x00#\x00\x01\xef\xcd\x00\xab\x90x\x00V4\x12\x00'
>>>
大整數(shù)和字節(jié)字符串之間的轉(zhuǎn)換操作并不常見(jiàn)。然而,在一些應(yīng)用領(lǐng)域有時(shí)候也會(huì)出現(xiàn),比如密碼學(xué)或者網(wǎng)絡(luò)。例如,IPv6網(wǎng)絡(luò)地址使用一個(gè)128位的整數(shù)表示。如果你要從一個(gè)數(shù)據(jù)記錄中提取這樣的值的時(shí)候,你就會(huì)面對(duì)這樣的問(wèn)題。
作為一種替代方案,你可能想使用6.11小節(jié)中所介紹的struct模塊來(lái)解壓字節(jié)。這樣也行得通,不過(guò)利用struct模塊來(lái)解壓對(duì)于整數(shù)的大小是有限制的。因此,你可能想解壓多個(gè)字節(jié)串并將結(jié)果合并為最終的結(jié)果,就像下面這樣:
>>> data
b'\x00\x124V\x00x\x90\xab\x00\xcd\xef\x01\x00#\x004'
>>> import struct
>>> hi, lo = struct.unpack('>QQ', data)
>>> (hi << 64) + lo
94522842520747284487117727783387188
>>>
字節(jié)順序規(guī)則(little或big)僅僅指定了構(gòu)建整數(shù)時(shí)的字節(jié)的低位高位排列方式。我們從下面精心構(gòu)造的16進(jìn)制數(shù)的表示中可以很容易的看出來(lái):
>>> x = 0x01020304
>>> x.to_bytes(4, 'big')
b'\x01\x02\x03\x04'
>>> x.to_bytes(4, 'little')
b'\x04\x03\x02\x01'
>>>
如果你試著將一個(gè)整數(shù)打包為字節(jié)字符串,那么它就不合適了,你會(huì)得到一個(gè)錯(cuò)誤。如果需要的話(huà),你可以使用 int.bit_length()
方法來(lái)決定需要多少字節(jié)位來(lái)存儲(chǔ)這個(gè)值。
>>> x = 523 ** 23
>>> x
335381300113661875107536852714019056160355655333978849017944067
>>> x.to_bytes(16, 'little')
Traceback (most recent call last):
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')
b'\x03X\xf1\x82iT\x96\xac\xc7c\x16\xf3\xb9\xcf...\xd0'
>>>
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話(huà):173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: