如何优化暴力破解程序速度以匹配在线估算的破解效率?
优化Python暴力破解程序的实用方案
嘿,我完全懂你的感受——那些在线密码破解估算工具的速度看起来遥不可及,但你的Python程序其实有不少可以压榨性能的空间。咱们先拆解原代码的瓶颈,再一步步优化到接近那些工具的效率。
原代码的核心瓶颈
你的代码主要慢在这几个地方:
- Python单线程的解释器开销:嵌套循环和每次字符串拼接、比较的操作在CPython里开销很大。
- 无用的遍历范围:你要破解的是6位密码,但代码从1位试到8位,前面1-5位的所有组合都是白忙活。
- 低效的字符串生成:每次用
itertools.product生成元组再join成字符串,这一步有额外的内存和时间开销。 - 未利用多核CPU:暴力破解是纯CPU密集型任务,但你的代码只用了单线程,浪费了大部分硬件性能。
分步优化方案
1. 先固定密码长度,减少无用计算
既然你知道目标密码的长度(比如测试的是6位),直接生成对应长度的组合,不用从1到8位遍历。这能立刻省去大量无效循环:
import itertools import time def tryPassword(passwordSet, stringTypeSet, password_length): start = time.time() chars = stringTypeSet attempts = 0 # 直接生成指定长度的组合 for letter_tuple in itertools.product(chars, repeat=password_length): attempts += 1 letter = ''.join(letter_tuple) if letter == passwordSet: end = time.time() return (attempts, end - start) password = "123456" stringType = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ`~!@#$%^&*()_-+=[{]}|:;'",<>/?" tries, timeAmount = tryPassword(password, stringType, len(password)) print(f"Cracked the password {password} in {tries} tries and {timeAmount:.4f} seconds!")
2. 用多进程压榨多核性能
Python的GIL(全局解释器锁)会限制单线程的CPU利用率,用multiprocessing把字符集分成多个块,每个进程处理一部分,能直接把速度提升到接近CPU核心数的倍数:
import itertools import time import multiprocessing from string import digits, ascii_lowercase, ascii_uppercase, punctuation # 提前定义字符集,比手动写更清晰高效 CHAR_SET = digits + ascii_lowercase + ascii_uppercase + punctuation def crack_chunk(target, chunk, length, result_queue): attempts = 0 for combo in itertools.product(chunk, repeat=length): attempts += 1 if ''.join(combo) == target: result_queue.put((attempts, True)) return result_queue.put((attempts, False)) def tryPassword(password): start = time.time() password_length = len(password) total_attempts = 0 # 把字符集分成和CPU核心数相等的块 num_processes = multiprocessing.cpu_count() chunk_size = len(CHAR_SET) // num_processes chunks = [CHAR_SET[i*chunk_size : (i+1)*chunk_size] for i in range(num_processes)] # 处理剩余的字符 if len(CHAR_SET) % num_processes != 0: chunks.append(CHAR_SET[num_processes*chunk_size:]) result_queue = multiprocessing.Queue() processes = [] for chunk in chunks: p = multiprocessing.Process( target=crack_chunk, args=(password, chunk, password_length, result_queue) ) processes.append(p) p.start() # 等待找到密码的进程返回 found = False while not found: attempts, is_found = result_queue.get() total_attempts += attempts if is_found: # 终止所有其他进程 for p in processes: if p.is_alive(): p.terminate() found = True end = time.time() return (total_attempts, end - start) if __name__ == "__main__": password = "123456" tries, timeAmount = tryPassword(password) print(f"Cracked the password {password} in {tries} tries and {timeAmount:.4f} seconds!")
3. 用JIT编译进一步提速(推荐PyPy或Numba)
如果用PyPy代替CPython运行你的代码,很多循环操作会被即时编译成机器码,速度能提升5-10倍甚至更多。
如果坚持用CPython,可以用numba给核心函数加JIT装饰器,不过numba对itertools的支持有限,我们可以改成手动生成组合:
import time from numba import jit @jit(nopython=True) def crack_password(target, char_set, length): target_bytes = target.encode('utf-8') char_bytes = [c.encode('utf-8')[0] for c in char_set] char_count = len(char_bytes) attempts = 0 # 手动生成组合(numba对递归支持不好,这里用循环实现) indices = [0] * length while True: attempts +=1 # 构建当前候选密码的字节 candidate = bytearray(length) for i in range(length): candidate[i] = char_bytes[indices[i]] if candidate == target_bytes: return attempts # 更新索引,类似进位 i = length -1 while i >=0: indices[i] +=1 if indices[i] < char_count: break indices[i] =0 i -=1 if i <0: break # 所有组合都试过了 return -1 def tryPassword(password): start = time.time() from string import digits, ascii_lowercase, ascii_uppercase, punctuation char_set = digits + ascii_lowercase + ascii_uppercase + punctuation attempts = crack_password(password, char_set, len(password)) end = time.time() return (attempts, end - start) password = "123456" tries, timeAmount = tryPassword(password) print(f"Cracked the password {password} in {tries} tries and {timeAmount:.4f} seconds!")
4. 其他小优化
- 提前转换密码为字节串:字节串的比较比字符串更快,尤其是在循环里。
- 避免全局变量:把常用的变量(比如字符集)作为参数传递,或者在函数内部定义,减少全局查找开销。
- 使用更快的字符比较:比如直接比较元组而不是拼接成字符串——把目标密码转成元组,然后和
itertools.product生成的元组直接比较,省去join的开销:
def tryPassword(passwordSet, stringTypeSet, password_length): start = time.time() chars = stringTypeSet target_tuple = tuple(passwordSet) attempts =0 for combo_tuple in itertools.product(chars, repeat=password_length): attempts +=1 if combo_tuple == target_tuple: end = time.time() return (attempts, end - start)
为什么在线工具那么快?
那些在线估算工具背后通常是用C/C++写的高度优化代码,甚至用GPU加速(比如CUDA),单线程性能就比Python高几十倍,再加上多核/多GPU的并行处理,速度自然夸张。但通过上面的优化,你的Python程序能大幅缩小差距,对于6-7位密码,应该能接近甚至达到1秒内破解的水平。
内容的提问来源于stack exchange,提问作者MickeyMouseFL
相关产品推荐
相关产品推荐

