“如何忽略”;FF FF“FF”;用python

“如何忽略”;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

我有一个大约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 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))