【发布时间】:2016-08-17 08:56:04
【问题描述】:
我有一些文件中包含 little-endian 编码字节,我想获取 N 字节,指定字节序并使用 python(任何版本)将它们转换为十进制数。如何正确操作?
【问题讨论】:
-
你可以使用struct模块。
N有多大? -
N可以达到文件大小。
标签: python endianness
我有一些文件中包含 little-endian 编码字节,我想获取 N 字节,指定字节序并使用 python(任何版本)将它们转换为十进制数。如何正确操作?
【问题讨论】:
N 有多大?
N 可以达到文件大小。
标签: python endianness
在 Python 3 中,您可以使用如下内容:
int.from_bytes(byte_string, byteorder='little')
【讨论】:
struct
正如 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 打印调用放在那里,这样您就可以轻松验证我的函数给出的结果与 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
当然,这会为m 使用一些 RAM,但它不会像用于反转输入字符串的 RAM 那么多。
【讨论】:
使用 Python 3(或 2),您可以通过 struct 库实现此目的。
with open('blob.dat', 'rb') as f:
data = f.read(n)
现在,您使用适当的format specifier string 解压。例如大端 int:
num = struct.unpack(">i",data)
【讨论】:
struct 在 Python2 中也可用,不是吗?