Python: 从二进制文件中提取奇怪数字/对十六进制与十进制的困惑

1 投票
3 回答
527 浏览
提问于 2025-04-15 18:33

这可能是个非常简单的问题,如果是这样我很抱歉,但我对我得到的输出感到非常困惑:十六进制?十进制?到底是什么?

这里有个例子,以及它返回的结果:

>>> print 'Rx State: ADC Clk=', ADC_Clock_MHz,'MHz DDC Clk=', DDC_Clock_kHz,'kHz Temperature=', Temperature,'C'
Rx State: ADC Clk= [1079246848L, 0L] MHz DDC Clk= [1078525952L, 0L] kHz Temperature= [1078140928L, 0L] C

我承认这有点猜测,因为我不太清楚数据到底是什么——我有一份说明,告诉我如何从文件中解析这些数据,但它给我的答案非常奇怪。

正如你所看到的,这些值非常相似,都在1078000000左右,这让我觉得我可能提取了一些奇怪的东西(像是十六进制,但我觉得不是……)

这个结构是这样读取的(抱歉有点长):

#Read block
    more = 1
    while(more == 1):
        a = array.array("L")
        a.fromfile(wholeFile,2)
        if len(a) == 2:
            structure_id = a[0]
            print 'structure_id: ', hex(structure_id)
            structure_length = a[1]
            print 'structure_length: ', structure_length
        else:
            print 'cannot read structure start'

        numDwords = (structure_length/4) - 2 - 1;
        print 'numDwords: ', numDwords

        content = array.array("L")
        content.fromfile(wholeFile,numDwords)
        if len(content) != numDwords:
            print 'cannot read structure'
            more = 0
            ok = 0

然后上面的例子是通过以下方式获取的:

pos = 2
v1 = [content[pos+1], content[pos]]
pos = pos+2
v2 = [content[pos+1], content[pos]]
pos = pos+2
v3 = [content[pos+1], content[pos]]
pos = pos+2

ADC_Clock_MHz = v1
DDC_Clock_kHz = v2
Temperature = v3

再次抱歉这么啰嗦,但不仅仅是这些值,似乎有些值正常而有些不正常,这让我觉得较大的数字可能是以不同的方式编码的……而且我也不知道为什么所有的值都是成对出现的!

这是个尴尬的问题,但如果有人能提供一些见解,我将非常感激。

3 个回答

0

你可能会觉得下面的方式更容易理解这个代码块。

如果你的数据没有正确解包,最可能的原因是头部并不只是两个长整型数字。或者,有可能是你的数据没有反映出你平台的“字节序”。

使用 struct 可以让你在格式字符串中添加一个 "<" 或 ">",这样可以尝试不同的字节序。此外,你也可以很方便地改变消息的格式,比如使用普通的整型、带符号的整型或者浮点数,而不需要做太多复杂的工作。

import struct
def read( someFile ):
    header= someFile.read( 8 )
    id, length = struct.unpack( "LL", header )
    print id, length
    body = someFile.read( length-8 ) # Common for length to include the header
    words = (length-8)//4
    content= struct.unpack( "L"*words, body )

你还可以打印 repr(header)repr(body),这样可以更好地了解你的数据实际是什么样子的。

0

这些内容是成对出现的,因为你把一对值赋给了变量(比如 ADC_Clock_MHz = v1v1 = [content[pos+1], content[pos]])。

实际上,你是把一个包含两个元素的列表赋值给 v1,其中第一个元素是数组 content 中索引为 pos+1 的元素,第二个元素是索引为 pos 的元素。

我有点搞不清楚你为什么要构建这个包含两个元素的列表。你是想把这两个元素合成一个数字吗?如果可以的话,能多告诉我们一些关于文件格式的信息吗?这是作业吗?

另外,不,这个输出不是十六进制的,而是十进制的。我觉得你可能在从二进制文件中读取数据时出错了。

0

发现用numpy.fromfile来做这个事情非常简单。

你只需要告诉它你想提取什么类型的数据(比如uint32、int16等等),它就会把这些数据提取成一个数组。你甚至可以自己定义类型,把已有的类型组合在一起,这样你就可以一次性提取已知的结构(比如先提取2个uint32,然后1个字符串,再提取5个int16,总共提取成一个包含8个值的数组)。

撰写回答