2016-05-09 2 views
3

Я пишу скрипт python (2.7) для сравнения двух списков. Эти списки создаются из файлов, читая их содержимое. Файлы - это только текстовые файлы, а не двоичные. Файл 1 содержит только хеши (сумма MD5 некоторого открытого текста), Файл 2 - хэш: обычный. Списки имеют разную длину (логически, я могу иметь менее «взломанные» записи, чем хэши), и оба не могут быть отсортированы по мере того, как я должен сохранять порядок, но это следующий шаг того, чего я пытаюсь достичь. До сих пор мой простой код выглядит следующим образом:два списка, более быстрое сравнение в python

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 

import sys 
import os 

def ifexists(fname): 
    if not os.path.isfile(fname): 
     print('[-] %s must exist' % fname) 
     sys.exit(1) 

if len(sys.argv) < 2: 
    print('[-] please provide CRACKED and HASHES files') 
    sys.exit(1) 

CRACKED=sys.argv[1] 
HASHES=sys.argv[2] 

sk_ifexists(CRACKED) 
sk_ifexists(HASHES) 

with open(CRACKED) as cracked, open(HASHES) as hashes: 
    hashdata=hashes.readlines() 
    crackdata=cracked.readlines() 
    for c in crackdata: 
     for z in hashdata: 
      if c.strip().split(':', 1)[0] in z: 
       print('found: ', c.strip().split(':', 1)) 

В принципе, я должен заменить хэш найден в списке хэшей с совпавшей строки хэша: обычный найден в крекинг списке. Я повторяю через CRACKED, поскольку он будет короче каждый раз. Поэтому моя проблема заключается в том, что выше код очень медленный для более длинных списков. Например, обработка двух текстовых файлов с линиями 60k занимает до 15 минут. Каково было бы ваше предложение ускорить его?

+0

Что о том, чтобы вытащить 'c.strip(). split (':', 1) [0]' в набор и хешировать в другой набор и искать пересечение двух множеств. – Bahrom

ответ

4

Храните один из этих файлов в словаре или наборе; который вынимает полный цикл, а поиск - это O (1) постоянное время в среднем.

Например, это выглядит как файл crackdata легко может быть преобразован в словарь:

with open(CRACKED) as crackedfile: 
    cracked = dict(map(str.strip, line.split(':')) for line in crackedfile if ':' in line) 

и теперь у вас есть только перебрать другой файл раз:

with open(HASHES) as hashes: 
    for line in hashes: 
     hash = line.strip() 
     if hash in cracked: 
      print('Found:', hash, 'which maps to', cracked[hash]) 
+0

Это замечательно. Теперь для завершения всей операции требуется около 1 с (60 тыс. Записей). Спасибо! – zerocool

Смежные вопросы