如何操作二进制文件并将结果写入另一个二进制文件

时间:2019-05-22 07:53:21

标签: python

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

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

数据成对出现,实际上字符串将表示为字节数组。我将有效地处理二进制数据。在上述示例中,有3对(\x00\x20 \x00\x2A \x02\x01)。我想更改输入文件,然后将其写入二进制文件。更改如下: 在每对中,如果第一项为0,则第二项将在输出文件中。如果第一项为1,则前一对中的第二项将在输出文件中。如果第一个项目大于1,那么它将更加复杂。这将取决于同一对中的2个项目。例如,如果第一个项目为2,第二个项目为1,则要获取输出编号,程序将在输出中返回2个项目,并将该项目用作输出。
example2:如果第一个项目是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])

,但是没有返回预期的输出。由于我在处理二进制文件方面还很陌生,因此您可以帮我修复它吗?或给我一些技巧以获得这种输出?

2 个答案:

答案 0 :(得分:0)

你没有那么远。首先,range允许仅自动使用第n个项目及其step参数,因此您可以使用:

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。

答案 1 :(得分:0)

首先,如果要基于每对的第一项做出决定,则应检查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的格式正确,如果不正确,则{{ 1}}的大小不足以容纳out