从文件读取小端并转换为十进制

4 投票
3 回答
12879 浏览
提问于 2025-04-18 14:49

我有一个文件,里面存储了无符号的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 个回答

1

根据这个评论:

现在它可以工作了,但我不确定它给我的输出是否正确(或者至少是我期待的输出)。假设文件的前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

就这样。

3

关键在于 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

… 这样就完成了。

4
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

我觉得应该可以工作...

撰写回答