我有一个大约60 kb的文件,我只想提取数据。该文件中有很多“FF FF FF FF”,我试图提取一切,但“FF FF FF FF”就是一个例子:
46 0D 89 2E 16 FC 1E E6 10 C1 6D 4E 1B 74 5F 1F
81 07 E2 E7 17 14 77 D4 EA AC BC 20 EA 98 27 FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
这是我用来获取它的代码:
infile = open("file.bin", "rb")
new_pos = int("0xFC0000", 16)
infile.seek(new_pos, 0)
chunk = int("0x40000", 16)
data = infile.read(chunk)
with open("processed_file.bin", "wb") as outfile:
outfile.write(data)
它将读取文件并将其保存为“processed file.bin”,但它中包含所有这些“FF FF”。有FF的实例,我需要它找到“FF FF FF FF”并将其从文件中删除,然后将其保存为已处理的文件.bin
任何意见都会受到赞赏。
编辑:为了进一步解释我的意思,这个十六进制在其末尾有FF,
81 07 E2 E7 17 14 77 D4 EA AC BC 20 EA 98 27 FF
我需要将FF保留在最后,但删除FF FF或FF FF FF FF的任何实例。
答案 0 :(得分:0)
首先,删除每个FF FF
显然需要删除每个FF FF FF FF
,因此您无需担心该部分。
如果您只想删除对齐的FF FF
,那么显而易见的事情就是将其分组为2字节的块。例如,使用标准库itertools recipes中的grouper
:
data = infile.read(chunk)
data_words = grouper(2, data)
data_words_minus_ffff = (word for word in data_words if word != ('\xFF', '\xFF'))
out_data = flatten(data_words_minus_ffff)
with open("processed_file.bin", "wb") as outfile:
outfile.write(''.join(out_data))
显然你可以更紧凑地写出来;我这样做是为了清晰起见(所以你可以尝试在每一步打印list(…)
以帮助理解它,以防它不明显。)
但是,如果你不关心对齐,你甚至想要删除FF
的奇数运行,只要它们长于1?好吧,那么你想将它分组为运行,并丢弃任何超过1的运行。你也可以用itertools
执行此操作:
data = infile.read(chunk)
groups = itertools.groupby(data, key=lambda x: x != '\xff')
groups_listified = ((key, list(group)) for key, group in groups)
groups_without_ff_runs = (group for key, group in groups_listified if key or len(group) > 1)
out_data = flatten(groups_without_ff_runs)
with open("processed_file.bin", "wb") as outfile:
outfile.write(''.join(out_data))
这个有点难以解释,但我再次把它写成一系列单独的步骤,所以你可以在每个步骤后print list(…)
看看它在做什么。
if key or len(group) > 1
位表示它是非FF字节的运行,或者是超过1个字节的运行。因此,如果您想将此更改为仅保留2字节的FF运行而不是更长的运行,则可以将len(group) > 1
更改为len(group) == 2
。如果您想保持偶数长度运行,请使用len(group) % 2 == 0
。等等。您可以描述的任何条件,都可以放在那里。
或者,为了多样化,让我们明确地做:
data = infile.read(chunk)
run = 0
out_data = []
for byte in data:
if byte == '\xFF':
run += 1
else:
if run != 1:
out_data.append('\xFF' * run)
run = 0
out_data.append(byte)
with open("processed_file.bin", "wb") as outfile:
outfile.write(''.join(out_data))
同样,我们保持FF
的所有长度超过1个字节的运行。如果您希望保留所有正好为2个字节的运行,只需将run != 1
更改为run == 2
即可。等等。