import hashlib
import multiprocessing
from itertools import product, islice
from string import printable
from datetime import datetime
import math
def get_config():
"""交互式配置爆破参数"""
print("MD5爆破工具 (超强优化版)")
print("-"*40)
while True:
target_hash = input("请输入目标MD5哈希值: ").strip().lower()
if len(target_hash) == 32 and all(c in '0123456789abcdef' for c in target_hash):
break
print("错误:必须输入有效的32位十六进制MD5哈希")
prefix = input("请输入拼接前缀(直接回车表示无前缀): ").strip()
max_length = int(input("最大尝试长度(推荐≤6): ") or 6)
chunk_size = int(input("分块大小(推荐内存1GB=625000): ") or 625000)
return {
'target_hash': target_hash,
'prefix': prefix,
'max_length': max_length,
'chunk_size': chunk_size,
'cpu_cores': multiprocessing.cpu_count()
}
def generate_candidates(charset, length, start, end):
"""基于数学计算生成候选字符串"""
base = len(charset)
for i in range(start, end):
candidate = []
n = i
for _ in range(length):
candidate.append(charset[n % base])
n = n // base
yield ''.join(reversed(candidate))
def hash_worker(args):
"""数学化分块爆破"""
target_hash, prefix, length, charset, chunk_start, chunk_size = args
start_time = datetime.now()
charset = tuple(charset)
total = len(charset) ** length
end = min(chunk_start + chunk_size, total)
prefix_bytes = prefix.encode()
target = target_hash
for candidate in generate_candidates(charset, length, chunk_start, end):
s = prefix + candidate
if hashlib.md5(s.encode()).hexdigest() == target:
return (candidate, length, datetime.now() - start_time)
return (None, length, datetime.now() - start_time)
def task_generator(config, primary_charset, full_charset):
"""动态生成任务(优先短长度+主字典)"""
for length in range(1, config['max_length']+1):
total = len(primary_charset) ** length
chunk_num = math.ceil(total / config['chunk_size'])
for chunk in range(chunk_num):
start = chunk * config['chunk_size']
yield (
config['target_hash'],
config['prefix'],
length,
primary_charset,
start,
config['chunk_size']
)
for length in range(1, config['max_length']+1):
total = len(full_charset) ** length
chunk_num = math.ceil(total / config['chunk_size'])
for chunk in range(chunk_num):
start = chunk * config['chunk_size']
yield (
config['target_hash'],
config['prefix'],
length,
full_charset,
start,
config['chunk_size']
)
def main():
try:
config = get_config()
dict_primary = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+-_"
dict_full = printable.strip()
start_time = datetime.now()
print("\n" + "="*60)
print(f" 目标哈希: {config['target_hash']}")
print(f" 前缀: '{config['prefix']}'" if config['prefix'] else " 无前缀")
print(f" CPU核心数: {config['cpu_cores']}")
print(f" 最大长度: {config['max_length']}")
print(f" 分块大小: {config['chunk_size']}")
print("="*60 + "\n")
with multiprocessing.Pool(config['cpu_cores']) as pool:
tasks = task_generator(config, dict_primary, dict_full)
found = False
for result in pool.imap_unordered(hash_worker, tasks, chunksize=4):
candidate, length, time_used = result
status = f"长度{length} 块完成 | 耗时{time_used}"
print(status.ljust(50), end='\r')
if candidate:
print("\n" + "="*40)
print(f"[+] 破解成功!原始输入 = {candidate}")
if config['prefix']:
print(f"[+] 完整字符串 = {config['prefix']}{candidate}")
print(f"[+] 破解长度 = {length}")
print(f"[+] 总耗时 = {datetime.now()-start_time}")
print("="*40)
found = True
break
if not found:
print("\n[!] 未在指定范围内找到匹配结果")
except KeyboardInterrupt:
print("\n[!] 用户终止操作")
if __name__ == "__main__":
main()