从文件读取小端并转换为十进制
我有一个文件,里面存储了无符号的64位整数,格式是小端字节序,下面是示例
0100 0000 0000 0000
0200 0000 0000 0000
0300 0000 0000 0000
3655 9d80 0f00 0000
7a64 dae3 0900 0000
060f fa3f 0600 0000
我想找个方法把这些数字读进来,然后转换成十进制的形式
到目前为止,我写的代码如下:
filename = "C:\\RainbowTables\\md5_loweralpha-numeric#1-7_0_2x50_0.rt"
blocksize = 8
with open(filename, "rb") as f:
startpoint = f.read(blocksize)
string = ""
for ch in startpoint:
string += hex(ord(ch))
print string
这段代码从第一个数字中输出了以下结果
0x10x00x00x00x00x00x00x0
我一直在研究如何使用结构体来处理这个问题,因为看起来这正是它的用途,但我一直找不到正确的语法来使用它们。
如果能得到任何帮助,我将非常感激!
3 个回答
根据这个评论:
现在它可以工作了,但我不确定它给我的输出是否正确(或者至少是我期待的输出)。假设文件的前8个字节是代码
0100 0000 0000 0000
,因为它是小端格式,这在正常的十六进制中应该是0000 0000 0000 0001
,我认为这在标准十进制中是1。但是,当我用两种方法运行它时,我得到的输出却是3472328296227680560L, 3472328296227680304L
。
我敢打赌你对文件格式的理解是错的。看看这个:
>>> hex(3472328296227680560L)
3030303030303030
现在,十六进制 30
是字符 '0'
的ASCII码。通过重新打包你解压的数据,你可以看到:
>>> struct.pack('<Q', 3472328296227680560L)
'00000000'
这足以告诉我们这个文件几乎可以肯定是一系列以ASCII十六进制编码的64位数字。虽然这还不足以告诉我们它们是否以某种方式分隔开。你需要查看文件来确认。(如果你不知道怎么在编辑器中做,或者用 cat
/type
之类的命令,直接用 print f.read(100)
打印前100个字符,然后把结果发到这里,其他人可以告诉你。)
但我们假设这些ASCII十六进制数字是用空格分开的。那么,你想要的是这个:
with open(path) as f:
for line in f:
hexnumbers = line.split()
for hexnumber in hexnumbers:
number = int(hexnumber, 16)
print number
就这样。
关键在于 struct
模块,特别是 struct.unpack
,就像 Joran Beasley 解释的那样。
所以,你需要循环读取文件,每次读取 8 个字节,直到文件结束:
filename = "C:\\RainbowTables\\md5_loweralpha-numeric#1-7_0_2x50_0.rt"
blocksize = 8
with open(filename, "rb") as f:
while True:
buf = f.read(blocksize)
if not buf:
break
… 将每 8 个字节解包为小端格式的 64 位无符号整数:
value = struct.unpack('<Q', buf)
… 然后你可以对每个数字做你想做的事情,比如把它加到一个列表里?… 不过现在我们先把它打印出来:
print value
… 这样就完成了。
import struct
decoded = []
with open("some_bin_file.rt","rb") as f:
while True:
try:
decoded.append(struct.unpack_from("<Q",f)[0])
# `<` means little endian; `Q` means unsigned long long (8 bytes)
except struct.error:
break
print decoded
我觉得应该可以工作...