2016-02-07 88 views
-1

我有一個字典output_dict,它包含與文件簽名及其相關擴展有關的數據,即'43 44 30 30 31': '.ISO'。我正在嘗試編寫一個腳本,它將以字節爲單位讀取文件並返回字典中的任何匹配項。如果找不到匹配,則返回最相似的值。將輸入字符串與類似的字典鍵匹配Python

有沒有辦法讓它逐字節地讀取一個文件,匹配它,直到達到一個破壞匹配的字節,返回先前匹配的鍵/值?

另外,我希望它能夠匹配一個確定的數量,或匹配非常相似的東西(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

「最相似的值」< - 定義? – timgeb

+0

其中「最相似的值」是一個僅相差2-3個字節的密鑰。 即,如果FF D8 EE 00不匹配,則返回FF D9 EE 00作爲可能的結果。 –

+0

不是很清楚要問什麼。 –

回答

0

發現這個有趣的,所以做了一個代碼片段,可能對你有用。假設每個字節都允許有一個小的差異。在您的評論中,如果控制值爲FF D8 EE 00,那麼FF D9 EE 00將是可接受的,那麼也可以接受FE D9 EF 01。在這個例子中,我設置了2作爲可接受的範圍,這意味着它將允許一個值小於或等於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_dictunknown變量讓你模擬從文件作爲琴絃的十六進制值的值。

你當然可以定義自己什麼是可接受的範圍,什麼類型的匹配是可以接受的。此代碼接受每個值對中的變體,但您可以輕鬆定義您需要至少有3個4是完全匹配。在示例unknownunknown2通過可接受的範圍內,而unknown3不在可接受的範圍內。

希望這給你一些你的計劃的想法。

+0

這看起來很有希望,我會看看它,看看它是否有幫助。謝謝一堆。 –