如何在Python中暴力破解5个字符以多进程或多线程破解sha256?

问题描述 投票:0回答:1

4个角色和Pool.map一切正常,运行时间约为46秒

import multiprocessing as mp
from tqdm import tqdm
from hashlib import sha256
from string import printable
from itertools import product, count

charset = printable[:-6]
chars = [c.encode() for c in charset]

def e(i):
    # sha256(W1n^r)  = 705c098135f1d15e28157c6424b17a7803ccbb6a218baaa312845de7b43303fe
    if sha256(i).hexdigest() == "705c098135f1d15e28157c6424b17a7803ccbb6a218baaa312845de7b43303fe":
        print(f"FOUND msg: {i}")
        return f"FOUND msg: {i}"

def g():
    for length in count(start=1):
        if length == 5:
            break
        for pwd in product(chars, repeat=length):
            yield b''.join(pwd)
    print("generator done")

if __name__ == '__main__':
    p = mp.Pool(4)
    for res in tqdm(p.map(e, g())):
        if res is not None:
            break

但是,当字符数增加到5个时,生成器过载,我的电脑崩溃了。 我查了一些建议使用 imap 的解决方案,但花了 2 个小时???而普通的暴力破解只需要大约 1 分 33 秒

https://i.stack.imgur.com/3cz1K.png

import multiprocessing as mp
from tqdm import tqdm
from hashlib import sha256
from string import printable
from itertools import product, count

charset = printable[:-6]
chars = [c.encode() for c in charset]

arr = []
def e(i):
    if sha256(i).hexdigest() == "705c098135f1d15e28157c6424b17a7803ccbb6a218baaa312845de7b43303fe": # W1n^r
        print(f"FOUND msg: {i}")
        return True

def g():
    for length in count(start=1):
        if length == 5:
            break
        for pwd in product(chars, repeat=length):
            yield b''.join(pwd)
    print("generator done")

if __name__ == '__main__':
    
    for i in tqdm(g(), total=78914410):
        res = e(i)
        if res is not None:
            break

我应该如何处理生成器,以便我可以将它与 mutilprocess 结合起来暴力破解 5 个字符?

python hash cryptography brute-force multiprocess
1个回答
0
投票

多处理优于多线程,因为核心功能受 CPU 限制。

您可以使用队列在主(父)进程和子进程之间进行通信。

以下代码在我的系统上运行了 12 分钟多一点。结果将根据平台以及子进程数量、批量大小和密码长度的变化而有所不同。

from multiprocessing import Process, Queue
from string import printable
from itertools import product, cycle
from hashlib import sha256
from queue import Empty
from time import perf_counter


PROCS = 7 # one less that CPU count
MAXLEN = 5
DIGEST = "705c098135f1d15e28157c6424b17a7803ccbb6a218baaa312845de7b43303fe"
BATCH = 10_000 # empirically determined to be a fairly good batch size

# check a batch of passwords
def process(qsend, qres):
    while batch := qsend.get():
        for v in map(str.encode, batch):
            if sha256(v).hexdigest() == DIGEST:
                qres.put(v)
                break

# generate passwords
def genpwd():
    for length in range(1, MAXLEN + 1):
        for pwd in product(printable[:-6], repeat=length):
            yield "".join(pwd)


def main():
    qres = Queue() # response queue
    # start PROCS processes each with a discrete input queue
    # each proc uses the same response queue
    procs = []
    for queue in (queues := [Queue() for _ in range(PROCS)]):
        (proc := Process(target=process, args=(queue, qres))).start()
        procs.append(proc)

    batch = []
    qc = cycle(queues)
    solution = None

    for pwd in genpwd():
        batch.append(pwd)
        if len(batch) == BATCH:
            # send batch to the next queue in the cycle
            next(qc).put(batch)
            batch = []
            # occasional check for a response
            try:
                solution = qres.get(block=False)
                break
            except Empty:
                pass

    # if there's no solution (yet) make sure anything left over in the batch list is submitted
    if not solution:
        next(qc).put(batch)
    
    # tells each process to stop
    for queue in queues:
        queue.put(None)

    # wait for all subprocesses to end
    for p in procs:
        p.join()

    # if there was no solution, check the response queue once more
    # ...because there could be subprocesses still running when the main loop ended (generator exhausted)
    if not solution:
        try:
            solution = qres.get(block=False)
        except Empty:
            pass

    if solution:
        print(f"Solution = {solution}")
    else:
        print("No solution found")

if __name__ == "__main__":
    start = perf_counter()
    main()
    end = perf_counter()
    duration = int(end - start)
    print(f"Duration={duration}s")

输出:

Solution = W1n^r
Duration=730s
© www.soinside.com 2019 - 2024. All rights reserved.