密码破解

问题

使用暴力破解包含大小写字母和数字的四位密码。

程序

import itertools
import time
import hashlib

def generate_hashes(passwords):
    """生成密码的MD5哈希值"""
    hashes = {}
    for pwd in passwords:
        hashes[pwd] = hashlib.md5(pwd.encode()).hexdigest()
    return hashes

def crack_by_hash(target_hashes):
    """通过哈希值破解密码"""
    characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
    
    print("开始破解密码...")
    start_time = time.time()
    attempts = 0
    found_passwords = {}
    
    # 记录每个密码的破解信息
    crack_info = {}
    
    # 生成所有1-3位字符组合
    for length in range(1, 5):
        for candidate in itertools.product(characters, repeat=length):
            password_attempt = ''.join(candidate)
            attempts += 1
            
            # 计算当前尝试密码的MD5哈希值
            hash_attempt = hashlib.md5(password_attempt.encode()).hexdigest()
            
            # 检查哈希值是否匹配任何目标
            for original_pwd, target_hash in target_hashes.items():
                if hash_attempt == target_hash and original_pwd not in found_passwords:
                    found_passwords[original_pwd] = password_attempt
                    crack_time = time.time() - start_time
                    crack_info[original_pwd] = {
                        'attempts': attempts,
                        'time': crack_time,
                        'found_password': password_attempt
                    }
                    print(f"✅ 破解成功: '{original_pwd}' -> '{password_attempt}'")
                    print(f"   尝试次数: {attempts}, 耗时: {crack_time:.4f}秒")
            
            # 如果所有密码都已找到,提前结束
            if len(found_passwords) == len(target_hashes):
                total_time = time.time() - start_time
                print(f"\n所有密码破解完成!")
                print(f"总尝试次数: {attempts}, 总耗时: {total_time:.4f}秒")
                return crack_info
    
    total_time = time.time() - start_time
    print(f"\n破解结束,找到 {len(found_passwords)}/{len(target_hashes)} 个密码")
    print(f"总尝试次数: {attempts}, 总耗时: {total_time:.4f}秒")
    return crack_info

def main():
    # 预存密码 - 代表最快和最后被遍历出来的密码
    passwords = ['a', '9', 'aa', '99', 'aaa', '999', 'aaaa', '9999']
    
    print("=" * 60)
    print("             密码哈希破解演示 (使用MD5)")
    print("=" * 60)
    
    # 生成并显示预存密码的哈希值
    print("\n预存密码及其MD5哈希值:")
    print("-" * 80)
    hashes = generate_hashes(passwords)
    
    for pwd, h in hashes.items():
        print(f"密码: '{pwd}' -> 哈希: {h}")
    
    print("-" * 80)
    
    # 显示字符集信息
    characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
    print(f"\n字符集: {characters}")
    print(f"字符集大小: {len(characters)}")
    print(f"1位密码组合数: {len(characters)}")
    print(f"2位密码组合数: {len(characters)**2}")
    print(f"3位密码组合数: {len(characters)**3}")
    print(f"4位密码组合数: {len(characters)**4}")
    print(f"总组合数: {len(characters) + len(characters)**2 + len(characters)**3 + len(characters)**4}")
    
    # 开始破解
    input("\n按回车键开始破解...")
    
    # 破解密码(只通过哈希值比较)
    results = crack_by_hash(hashes)
    
    # 显示破解结果总结
    print("\n" + "=" * 60)
    print("破解结果总结:")
    print("-" * 60)
    
    # 按破解顺序显示
    for pwd in passwords:
        if pwd in results:
            info = results[pwd]
            print(f"密码 '{pwd}': {info['attempts']:6d} 次尝试, {info['time']:.4f} 秒")
        else:
            print(f"密码 '{pwd}': 未找到")
    
    print("=" * 60)

if __name__ == "__main__":
    main()

执行效果

============================================================
             密码哈希破解演示 (使用MD5)
============================================================

预存密码及其MD5哈希值:
--------------------------------------------------------------------------------
密码: 'a' -> 哈希: 0cc175b9c0f1b6a831c399e269772661
密码: '9' -> 哈希: 45c48cce2e2d7fbdea1afc51c7c6ad26
密码: 'aa' -> 哈希: 4124bc0a9335c27f086f24ba207a4912
密码: '99' -> 哈希: ac627ab1ccbdb62ec96e702f07f6425b
密码: 'aaa' -> 哈希: 47bce5c74f589f4867dbd57e9ca9f808
密码: '999' -> 哈希: b706835de79a2b4e80506f582af3676a
密码: 'aaaa' -> 哈希: 74b87337454200d4d33f80c4663dc5e5
密码: '9999' -> 哈希: fa246d0262c3925617b0c72bb20eeb1d
--------------------------------------------------------------------------------

字符集: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
字符集大小: 62
1位密码组合数: 62
2位密码组合数: 3844
3位密码组合数: 238328
4位密码组合数: 14776336
总组合数: 15018570

按回车键开始破解...
开始破解密码...
✅ 破解成功: 'a' -> 'a'
   尝试次数: 1, 耗时: 0.0000秒
✅ 破解成功: '9' -> '9'
   尝试次数: 62, 耗时: 0.0006秒
✅ 破解成功: 'aa' -> 'aa'
   尝试次数: 63, 耗时: 0.0010秒
✅ 破解成功: '99' -> '99'
   尝试次数: 3906, 耗时: 0.0053秒
✅ 破解成功: 'aaa' -> 'aaa'
   尝试次数: 3907, 耗时: 0.0055秒
✅ 破解成功: '999' -> '999'
   尝试次数: 242234, 耗时: 0.2391秒
✅ 破解成功: 'aaaa' -> 'aaaa'
   尝试次数: 242235, 耗时: 0.2394秒
✅ 破解成功: '9999' -> '9999'
   尝试次数: 15018570, 耗时: 14.6867秒

所有密码破解完成!
总尝试次数: 15018570, 总耗时: 14.6869秒

============================================================
破解结果总结:
------------------------------------------------------------
密码 'a':      1 次尝试, 0.0000 秒
密码 '9':     62 次尝试, 0.0006 秒
密码 'aa':     63 次尝试, 0.0010 秒
密码 '99':   3906 次尝试, 0.0053 秒
密码 'aaa':   3907 次尝试, 0.0055 秒
密码 '999': 242234 次尝试, 0.2391 秒
密码 'aaaa': 242235 次尝试, 0.2394 秒
密码 '9999': 15018570 次尝试, 14.6867 秒
============================================================