我有一个二进制文件,当我在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])
,但是没有返回预期的输出。由于我在处理二进制文件方面还很陌生,因此您可以帮我修复它吗?或给我一些技巧以获得这种输出?
答案 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开始。
您收到错误消息,因为您的n
是int
,因此不能在其上使用切片([]
运算符)。
此外,由于您想返回输出,因此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
。