我有一个字典output_dict
,其中包含与文件签名及其相关扩展名相关的数据,即'43 44 30 30 31': '.ISO'
。我正在尝试编写一个脚本,它将以字节为单位读取文件并返回字典中的任何匹配项。如果未找到匹配项,则返回最相似的值。
有没有办法让它逐字节读取文件,匹配直到它到达一个打破匹配的字节,返回先前匹配的键/值?
或者,我希望它能够匹配一定数量,或匹配非常相似的东西(2-3个字节的差异)。如果没有匹配或没有相似的对象,我会希望它打印一条消息。
目前,我的代码如下所示:
root_path = "testdir"
list_of_files = os.listdir(root_path)
for files in list_of_files:
full_path = os.path.join(root_path, files)
open_it = open(full_path, 'rb')
read_it = open_it.read(x)
convert_it = get_bytes_as_displayable_hex(read_it)
convert_to_ascii = convert_it.encode('utf-8')
convert_to_string = convert_to_ascii.decode(encoding='utf-8', errors="strict")
result = (output_dict.get(convert_to_string))
if result is not None:
print("Scan complete, found: {} file(s)".format(result))
else:
result = difflib.get_close_matches(convert_to_string, output_dict, 2, 0.2)
print(result)
因此,预期结果将类似于文件的前4个字节是25 50 44 46.这些字节与字典交叉引用并匹配它,返回" .PDF"结果。
如果前四个字节是25 50 44 47,这不在字典中,但代码仍将返回" .PDF"结果是因为它们非常相似。
感谢任何帮助,以及任何建议,因为我对Python和编程非常陌生。
答案 0 :(得分:0)
发现这很有趣,所以制作了一个可能对你有用的代码片段。假设允许每个字节有一个小的差异。与您的评论一样,如果控件值为FF D9 EE 00
,则FF D8 EE 00
可以接受,那么FE D9 EF 01
也是可以接受的。在示例中,我将2
设置为可接受的范围,这意味着它将允许值小于或小于控制值的值。
def create_list(value):
# Convert a byte sequence (as string) into a list of int values.
return [int(value[i:i + 2], 16) for i in range(0, len(value), 2)]
def check_if_close(value, control_value, accepted_range):
print('Checking {} vs {}'.format(value, control_value))
value = create_list(value)
control_value = create_list(control_value)
count = 0
exact_match = 0
for x in range(len(value)):
if value[x] == control_value[x]:
exact_match += 1
continue
for y in range(control_value[x] - accepted_range,
control_value[x] + accepted_range + 1):
if y == value[x]:
count += 1
print('Unknown: {}, Predefined: {}'.format(y, control_value[x]))
print('Exact matches:', exact_match)
print('Bytes within range:', count)
if exact_match + count == len(value):
print('-- Within acceptable range\n')
else:
print('-- Not within acceptable range\n')
predefined = 'FFD8EE00'
unknown = 'FFD9EE00'
unknown2 = 'FED9EF01'
unknown3 = 'FFEFEE00'
check_if_close(unknown, predefined, 2)
check_if_close(unknown2, predefined, 2)
check_if_close(unknown3, predefined, 2)
predefined
将是您从output_dict
获得的值,unknown
变量模拟您从文件中获得的十六进制值作为字符串。
您当然可以定义自己可接受的范围,以及可接受的匹配类型。此代码接受每个值对的变体,但您可以轻松定义至少需要4个中的3个才能完全匹配。示例unknown
和unknown2
在可接受的范围内通过,而unknown3
不在可接受的范围内。
希望这可以为您的计划提供一些想法。