如何将 python 中的 blob 转换为整数?
How to convert blob to integer in python?
我有一些包含小端编码字节的文件,我想使用 N
字节,指定字节顺序并使用 python(任何版本)将它们转换为十进制数。如何正确操作?
在 Python 3 中你可以使用这样的东西:
int.from_bytes(byte_string, byteorder='little')
使用 Python 3(或 2),您可以使用 struct 库实现此目的。
with open('blob.dat', 'rb') as f:
data = f.read(n)
现在,您使用适当的 format specifier string 解压。例如,big-endian int:
num = struct.unpack(">i",data)
正如 Harshad Mulmuley 的回答所示,这在 Python 3 中很容易,使用 int.from_bytes
方法。在 Python 2 中,它有点棘手。
struct
模块设计用于处理标准 C 数据类型。它不会处理任意长度的整数(Python 2 long
整数),因为它们不是 C 的本机整数。但是您可以使用简单的 for
循环转换它们。我预计这将比 Python 3 方式慢得多,因为 Python for
循环比以 C 速度循环慢,就像 int.from_bytes
(可能)那样。
from binascii import hexlify
def int_from_bytes_LE(s):
total = 0
for c in reversed(s):
total = (total << 8) + ord(c)
return total
# Test
data = (
(b'\x01\x02\x03\x04', 0x04030201),
(b'\x01\x02\x03\x04\x05\x06\x07\x08', 0x0807060504030201),
(b'\x01\x23\x45\x67\x89\xab\xcd\xef\x01\x23\x45\x67\x89\xab\xcd\xef',
0xefcdab8967452301efcdab8967452301),
)
for s, u in data:
print hexlify(s), u, int_from_bytes_LE(s)
#print(hexlify(s), u, int.from_bytes(s, 'little'))
输出
01020304 67305985 67305985
0102030405060708 578437695752307201 578437695752307201
0123456789abcdef0123456789abcdef 318753391026855559389420636404904698625 318753391026855559389420636404904698625
(我把 Python 3 print 调用放在那里,这样你就可以很容易地验证我的函数给出与 int.from_bytes
相同的结果)。
如果您的数据真的很大并且您不想浪费 RAM 来反转字节字符串,您可以这样做:
def int_from_bytes_LE(s):
m = 1
total = 0
for c in s:
total += m * ord(c)
m <<= 8
return total
当然,这会使用一些 RAM m
,但不会像用于反转输入字符串的 RAM 那样多。
我有一些包含小端编码字节的文件,我想使用 N
字节,指定字节顺序并使用 python(任何版本)将它们转换为十进制数。如何正确操作?
在 Python 3 中你可以使用这样的东西:
int.from_bytes(byte_string, byteorder='little')
使用 Python 3(或 2),您可以使用 struct 库实现此目的。
with open('blob.dat', 'rb') as f:
data = f.read(n)
现在,您使用适当的 format specifier string 解压。例如,big-endian int:
num = struct.unpack(">i",data)
正如 Harshad Mulmuley 的回答所示,这在 Python 3 中很容易,使用 int.from_bytes
方法。在 Python 2 中,它有点棘手。
struct
模块设计用于处理标准 C 数据类型。它不会处理任意长度的整数(Python 2 long
整数),因为它们不是 C 的本机整数。但是您可以使用简单的 for
循环转换它们。我预计这将比 Python 3 方式慢得多,因为 Python for
循环比以 C 速度循环慢,就像 int.from_bytes
(可能)那样。
from binascii import hexlify
def int_from_bytes_LE(s):
total = 0
for c in reversed(s):
total = (total << 8) + ord(c)
return total
# Test
data = (
(b'\x01\x02\x03\x04', 0x04030201),
(b'\x01\x02\x03\x04\x05\x06\x07\x08', 0x0807060504030201),
(b'\x01\x23\x45\x67\x89\xab\xcd\xef\x01\x23\x45\x67\x89\xab\xcd\xef',
0xefcdab8967452301efcdab8967452301),
)
for s, u in data:
print hexlify(s), u, int_from_bytes_LE(s)
#print(hexlify(s), u, int.from_bytes(s, 'little'))
输出
01020304 67305985 67305985
0102030405060708 578437695752307201 578437695752307201
0123456789abcdef0123456789abcdef 318753391026855559389420636404904698625 318753391026855559389420636404904698625
(我把 Python 3 print 调用放在那里,这样你就可以很容易地验证我的函数给出与 int.from_bytes
相同的结果)。
如果您的数据真的很大并且您不想浪费 RAM 来反转字节字符串,您可以这样做:
def int_from_bytes_LE(s):
m = 1
total = 0
for c in s:
total += m * ord(c)
m <<= 8
return total
当然,这会使用一些 RAM m
,但不会像用于反转输入字符串的 RAM 那样多。