0

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

它将读取文件并将其保存为“已处理的 file.bin”,但其中包含所有这些“FF FF”。有FF的实例,我需要它找到“FF FF FF FF”并将其从文件中删除,然后再将其保存为已处理的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 的实例。

4

1 回答 1

0

首先,删除 everyFF FF显然会删除 every FF FF FF FF,因此您无需担心该部分。

如果您只想删除对齐FF FF的 s,显而易见的做法是将其分组为 2 字节的块。例如,使用grouper标准库的itertools recipes

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) > 1len(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 != 1run == 2. 等等。

于 2013-01-29T01:43:09.850 回答