“如何忽略”;FF FF“FF”;用python
我有一个大约60KB的文件,我只想提取数据。该文件中有很多“FF FF FF FF”,我正在尝试提取所有内容,但“FF FF FF FF FF FF”是一个示例:“如何忽略”;FF FF“FF”;用python,python,Python,我有一个大约60KB的文件,我只想提取数据。该文件中有很多“FF FF 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
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”并将其从文件中删除,然后再将其保存为processed file.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 FF
显然需要删除每个FF FF FF
,因此您不必担心该部分
如果您只想删除对齐的FF FF
s,那么显而易见的做法是将其分组为2字节块。例如,使用标准库中的grouper
:
显然,你可以写得更简洁;我这样做只是为了清晰(所以你可以试着在每一步打印出列表(…)
,以帮助理解它,以防不明显)
但是,如果您不关心对齐,甚至想要删除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))
这一步有点难以解释,但我还是把它写成了一系列单独的步骤,所以你可以在每一步之后打印列表(…)
,看看它在做什么
if key或len(group)>1位表示它是非FF字节的运行,或者它是超过1字节的运行。因此,如果您想将其更改为仅保留2字节FF运行,而不是更长的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))
同样,我们将保留所有长度超过1字节的FF
。如果您想保留正好为2字节的所有运行,只需更改run!=1
到运行==2
。依此类推。是否只想删除对齐的FF FF
?换句话说,对于00 FF FF 03
,是否应该删除FF FF
?是的,我想保留“FF”,但删除“FF FF”或“FF FF FF”或“FF FF FF FF”,如果这样做有意义的话,这并不能直接回答我的问题,但是你想要删除的事实意味着答案…所以让我更新我的答案来解释这个版本。顺便说一下,没有理由做int(“0xFC0000”,16)
-这和0xFC0000
@isedev是一样的:OP没有指定,但我很确定他的二进制文件实际上不是ASCII字符'46 0D 89 2E…
,而是字节'\x46\x0d\x89\x2e…
。(换句话说,他向我们展示了文件的十六进制转储,而不是cat。)否则,他为什么要以二进制模式打开它?@abarnert。。。是的,后来意识到:)好的,我刚刚意识到,请不要开枪打我^^^但有些情况下我需要保留FF FF FF,并删除除FF FF以外的任何内容,你的代码确实有效,但删除了6字节的数据,即FF FF的3个实例,所以我需要保留FF并删除任何内容more@james28909:如果要保留所有长度不完全为2字节的运行,只需将len(group)==1
更改为len(group)!=2
(或者,对于更明确的解决方案,如果run==1,则等效为到如果run!=2
)。
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))