2012-08-02 130 views
3

我使用Python 2.7,和我有一個簡單的MD5 multitheaded字典蠻力:在5個一線MD5多線程暴力破解

# -*- coding: utf-8 -*- 

import md5 
import Queue 
import threading 
import traceback 

md5_queue = Queue.Queue() 


def Worker(queue): 
    while True: 
     try: 
      item = md5_queue.get_nowait() 
     except Queue.Empty: 
      break 
     try: 
      work(item) 
     except Exception: 
      traceback.print_exc() 

     queue.task_done() 


def work(param): 
    with open('pwds', 'r') as f: 
     pwds = [x.strip() for x in f.readlines()] 

    for pwd in pwds: 
     if md5.new(pwd).hexdigest() == param: 
      print '%s:%s' % (pwd, md5.new(pwd).hexdigest()) 


def main(): 
    global md5_queue 
    md5_lst = [] 
    threads = 5 

    with open('md5', "r") as f: 
     md5_lst = [x.strip() for x in f.readlines()] 

    for m in md5_lst: 
     md5_queue.put(m) # add md5 hash to queue 

    for i in xrange(threads): 
     t = threading.Thread(target=Worker, args=(md5_queue,)) 
     t.start() 

    md5_queue.join() 


if __name__ == '__main__': 
    main() 

工作。每個線程從隊列中讀取一個散列,並使用密碼列表對其進行檢查。非常簡單:1線程1簽入'for'循環。

我想多一點:1個線程和幾個線程來檢查密碼。所以work()應該從隊列中讀取哈希值並啓動新的線程數來檢查密碼(1個線程哈希,10個線程在那裏檢查密碼)。例如:20個線程用哈希和20個線程在每個線程中搗亂哈希。類似的東西。

我該怎麼做?

P.S.對不起,我的解釋,問你是否不明白我想要什麼。

P.P.S.這不是關於brd md5,而是關於多線程。

謝謝。

回答

4

Python的默認實現(稱爲CPython)使用Global Interpreter Lock(GIL),它實際上只允許一次運行一個線程。對於I/O綁定的多線程應用程序,這通常不是問題,但對於像您這樣的CPU綁定應用程序,這意味着您不會看到太多的多核加速。

我建議使用不具有GIL的不同Python實現(如Jython),或者重寫代碼以使用不具有GIL的其他語言。把它寫入本地編譯的代碼是一個不錯的主意,但是大多數具有MD5函數的腳本語言通常都會在本地代碼中實現它,所以老實說,在本地編譯語言和腳本語言之間不會有很大的提速。

+0

那麼,還有另一種使用所有內核的解決方案 - 多處理。標準庫中的這個模塊具有類似於線程的API,並且允許擺脫GIL限制。儘管你沒有收到任何線索,但進程正在完成這項工作。 – 2012-08-02 19:17:50

1

我相信,下面的代碼將是一個有效的多方案比你的示例代碼:

from __future__ import with_statement 

try: 
    import md5 
    digest = lambda text: md5.new(text).hexdigest() 
except ImportError: 
    import hashlib 
    digest = lambda text: hashlib.md5(text.encode()).hexdigest() 

def main(): 
    passwords = load_passwords('pwds') 
    check_hashes('md5', passwords) 

def load_passwords(filename): 
    passwords = {} 
    with open(filename) as file: 
     for word in (line.strip() for line in file): 
      passwords.setdefault(digest(word), []).append(word) 
    return passwords 

def check_hashes(filename, passwords): 
    with open(filename) as file: 
     for code in (line.strip() for line in file): 
      for word in passwords.get(code,()): 
       print (word + ':' + code) 

if __name__ == '__main__': 
    main() 

已使用Python編寫的2.x和3.x都和應該能夠運行這兩種語言之一。