【问题标题】:how to manipulate a binary file and write the results into another binary file如何操作二进制文件并将结果写入另一个二进制文件
【发布时间】:2019-05-22 20:26:36
【问题描述】:

我有一个二进制文件,当我在 python 中解析它时,内容将如下所示:

b'\x00\x20\x00\x2A\x02\x01'

数据是成对出现的,实际上字符串将被表示为字节数组。我将有效地处理二进制数据。在上述示例中,有 3 对 (\x00\x20 \x00\x2A \x02\x01)。我想更改输入文件,然后将其写入二进制文件。变化如下: 在每一对中,如果第一项为 0,则第二项将在输出文件中。如果第一项是 1,则前一对中的第二项将在输出文件中。如果第一项大于 1,那么它会更复杂。这将取决于同一对中的 2 个项目。例如 1,如果第 1 项是 2,而第 2 项是 1,为了得到输出的数字,程序在输出中返回 2 项并将该项用作输出。
示例 2:如果第一项是 2,第二项是 2,为了得到输出的数字,程序在输出中返回 2 项,并使用该项加上之后的 1 项作为输出。

这是预期的输出:

b'\x20\x2A\x20'

我尝试在 python 中使用以下代码:

data = b'\x00\x20\x00\x2A\x02\x01'

out = bytearray()
for i in range(len(data)):
    if i % 2 !=0:
        if data[i] ==0:
        out.append(data[i+1])
        elif data[i] ==1:
        out.append(data[i-1])
        elif data[i] >1:
            n = data[i]
            for j in range(n):
                out.append(n[0:j])

但它没有返回预期的输出。因为我在处理二进制文件方面很陌生,你能帮我解决它吗?或者给我一些提示来获得这样的输出?

【问题讨论】:

  • 如果你能展示你期望的输出和你得到的结果会很好。
  • 回溯(最近一次调用最后):文件“”,第 10 行,在 类型错误:'int' 对象不可下标

标签: python


【解决方案1】:

你没那么远。首先,range 允许自动只使用每一个带有其 step 参数的第 n 项,因此您可以使用:

for i in range(0,len(data),2):

接下来,与您的文字不一致的最后一个块:

        n = data[i]
        for j in range(n):       # according to your text, it should be n = data[i+1]
            out.append(n[0:j])   # non sensible expression: n is an integer

要获得预期的数据,您应该使用:

        n = data[i+1]
        for j in range(n):
            out.append(data[i-3+2*j])

但请注意,此代码盲目地相信 data 输入是正确的,如果操作需要不存在的字节,则会引发 KeyError。

【讨论】:

    【解决方案2】:

    首先,如果您想根据每对的第一个项做出决定,您应该检查i % 2 == 0,否则data[i] 将始终是您对的第二项。这是因为计数器从 0 开始。

    您收到错误消息,因为您的 nint,因此您不能对其使用切片([] 运算符)。

    此外,data[i] > 1 的代码完全不适合您在示例中描述的内容,因为您想返回 输出

    更像是:

    data = b'\x00\x20\x00\x2A\x02\x01'
    
    out = bytearray()
    for i in range(len(data)):
      if i % 2 == 0:
        if data[i] == 0:
          out.append(data[i+1])
        elif data[i] == 1:
          out.append(data[i-1])
        elif data[i] > 1:
          n = data[i]
          for j in range(n):
            out.append(out[-2])  # take the item 2 steps back from the end of "out"
    

    out 将是一个带有值[32, 42, 32, 42] 的字节数组,即使print(out) 将输出bytearray(b' * *')

    但请记住,正如@Serge Ballesta 在他的回答中所说:您的程序完全相信data 的格式正确,如果不是,您将遇到问题,例如当out 是索引超出范围时out[-2] 不够大。

    【讨论】:

    • 谢谢,但仍然没有返回预期的输出。这是这段代码的输出: bytearray(b' * *')
    • 这是因为字节的字符串表示。如果您运行int.from_bytes(out[0], "big"),您将看到正确的值是32。您甚至可以在开头添加print(data),以查看字符串表示不适合您作为输入的内容。
    猜你喜欢
    • 2019-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-05
    • 1970-01-01
    • 2017-06-30
    相关资源
    最近更新 更多