MD5多线程暴力破解

3
我使用Python 2.7,并且我有一个简单的多线程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()

使用5个线程。每个线程从队列中读取一个哈希值,并将其与密码列表进行比较。非常简单:1个线程在'for'循环中进行1次检查。

我想要更多一点:1个线程和几个线程来检查密码。因此,work()应该从队列中读取哈希值,并启动一些新的线程来检查密码(1个线程哈希值,10个线程检查密码)。例如:20个线程用于哈希值,以及每个线程中用于暴力破解哈希值的20个线程。就像这样。

我该如何做到这一点?

P.S. 对不起我的解释可能有误,请问如果你没有理解我想要什么。

P.P.S. 这不是关于暴力破解MD5,而是关于多线程。

谢谢。

2个回答

4
Python的默认实现(称为CPython)使用全局解释器锁(GIL),这有效地只允许一个线程同时运行。对于I/O绑定的多线程应用程序,这通常不是问题,但对于像你这样的CPU绑定的应用程序,这意味着你不会看到太多的多核加速。我建议使用没有GIL的不同Python实现,例如Jython,或重写您的代码以使用没有GIL的不同语言。将其编写为本地编译代码是一个好主意,但大多数具有MD5函数的脚本语言通常已经在本地代码中实现了该函数,因此我真的不会期望在本地编译语言和脚本语言之间看到太多加速。

好的,还有另一种解决方案可以使用所有核心 - 多进程。这个标准库中的模块具有类似于线程的API,并允许摆脱GIL的限制。虽然你没有线程,但是有进程来完成工作。 - Rostyslav Dzinko

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编写,也可以用Python 3.x编写,并且应该能够在这两种语言中运行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接