Python哈希暴力破解脚本实现指定起始字符断点续跑方案咨询
哈希暴力破解脚本断点续算实现思路
核心逻辑是利用itertools.product生成候选序列的顺序完全遵循传入字符集的排列顺序的特性,跳过所有断点之前的候选,直接从断点下一个候选开始计算。具体实现步骤如下:
- 合法性校验:首先校验传入的起始序列
start_char是否合法:所有字符都属于选定的爆破字符集、长度在设定的爆破长度区间内,不合法则直接从初始状态开始计算。 - 调整候选生成逻辑:
- 直接跳过所有长度小于
start_char长度的候选组合 - 对于长度等于
start_char长度的组合,仅保留字典序(和product生成顺序保持一致)大于start_char的部分 - 长度大于
start_char长度的组合按原有逻辑正常生成
- 直接跳过所有长度小于
- 可选:增加自动进度持久化能力,运行过程中定时(比如每尝试10万次)将当前最后尝试的序列写入本地进度文件,程序中断后下次启动自动读取进度文件内容作为起始点,无需手动传入。
注意:不要直接用Python默认的字符串大小比较判断候选顺序,默认比较用的是Unicode码点顺序,如果你自定义的字符集顺序和Unicode顺序不一致会出现偏差,需要基于字符在你自定义字符集中的索引做比较。
修改后的完整代码
import hashlib import time import os from itertools import product class Hashing: def __init__(self, hashing: str, algorithm: str, character_type: list, item: list, start_char: str = None): self.character = {'letter': 'abcdefghijklmnopqrstuvwxyz', 'number': '0123456789', 'maj': 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'space': ' ', 'speciaux': """<>&é"'(-è_çà)=ù!:;,+%§/.?*µ~#}{[|`\^@]¤"""} self.character_type = character_type self.combinaison_number = 0 self.algorithm = algorithm self.start_char = start_char # 自动读取本地进度文件,优先级低于手动传入的start_char if self.start_char is None and os.path.exists('brute_progress.txt'): with open('brute_progress.txt', 'r', encoding='utf-8') as f: self.start_char = f.read().strip() self.item = item self.hashing = hashing self.result = None self.extend = "" def bruteforce(self, charset, maxlength): min_len = self.item[0] max_len = maxlength # 生成字符到索引的映射,保证比较逻辑和product生成顺序完全一致 char_idx = {c: idx for idx, c in enumerate(charset)} def candidate_greater(candidate_tuple, target_str): for c, t in zip(candidate_tuple, target_str): if char_idx[c] > char_idx[t]: return True if char_idx[c] < char_idx[t]: return False return False if self.start_char is not None: start_len = len(self.start_char) # 校验start_char合法性 if start_len < min_len or start_len > max_len or any(c not in char_idx for c in self.start_char): self.start_char = None yield from self.bruteforce(charset, maxlength) return for length in range(min_len, max_len + 1): # 跳过长度小于start_char长度的所有组合 if length < start_len: continue for candidate in product(charset, repeat=length): if length == start_len: if not candidate_greater(candidate, self.start_char): continue yield ''.join(candidate) else: # 无起始点时走原有逻辑 for length in range(min_len, max_len + 1): for candidate in product(charset, repeat=length): yield ''.join(candidate) def start(self): for i in self.character_type: self.extend += self.character.get(i, '') if self.algorithm == "md5": self.algo_md5() elif self.algorithm == "sha256": self.algo_sha256() def save_progress(self, current_attempt): # 每10万次保存一次进度,可根据自己的运算速度调整阈值 if self.combinaison_number % 100000 == 0: with open('brute_progress.txt', 'w', encoding='utf-8') as f: f.write(current_attempt) def algo_md5(self): start_time = time.time() for attempt in self.bruteforce(self.extend, self.item[1]): self.combinaison_number +=1 self.save_progress(attempt) if hashlib.md5(attempt.encode('utf-8')).hexdigest() == self.hashing: self.print_result(attempt, start_time) # 破解成功后删除进度文件 if os.path.exists('brute_progress.txt'): os.remove('brute_progress.txt') break def algo_sha256(self): start_time = time.time() for attempt in self.bruteforce(self.extend, self.item[1]): self.combinaison_number +=1 self.save_progress(attempt) if hashlib.sha256(attempt.encode('utf-8')).hexdigest() == self.hashing: self.print_result(attempt, start_time) if os.path.exists('brute_progress.txt'): os.remove('brute_progress.txt') break def print_result(self, attempt, start_time): print(f"The result is `{attempt}` with {self.combinaison_number} test\n{self.combinaison_number/(time.time()-start_time)} test in 1 secondes") if __name__ == "__main__": # 手动指定起始点示例:Hashing(..., start_char="abcde") Hash = Hashing("3ed7dceaf266cafef032b9d5db224717", "md5", ['letter', 'number'], [1, 10]) Hash.start()
用法说明
- 手动指定起始点:初始化
Hashing类时传入start_char参数即可,比如start_char="abcde"就会从abcde的下一个候选开始计算 - 自动续跑:程序运行过程中会自动每10万次保存一次进度到当前目录的
brute_progress.txt文件,下次启动时如果不指定start_char会自动读取该文件的内容作为起始点,破解成功后会自动删除该文件。
内容的提问来源于stack exchange,提问作者Jourdelune
相关产品推荐
相关产品推荐

