高级密码生成器程序详解:专门设计用于生成基于用户个人信息的密码猜测组合

一、程序概述与功能分析

1.1 程序定位与应用场景

本程序是一个高级密码生成器,专门设计用于生成基于用户个人信息的密码猜测组合。该工具主要应用于以下场景:

  • 安全测试与渗透测试:帮助安全专业人员评估系统密码强度

  • 数字取证调查:协助执法部门恢复或猜测嫌疑人的密码

  • 用户行为研究:分析用户设置密码的常见模式和习惯

  • 密码策略评估:验证组织密码策略的有效性

1.2 核心功能特点

程序具备以下核心功能:

  1. 智能数据解析:能够解析包含多种个人信息字段的输入数据

  2. 分层难度系统:根据用户数据所在行号自动划分难度等级(普通/中等/困难)

  3. 多策略生成:针对不同难度级别采用不同的密码生成策略

  4. 上下文感知:结合个人信息、常见模式、键盘模式等多种元素

  5. leet语变形:支持字符替换的高级密码变形技术

  6. 统计分析:提供生成过程的详细统计和分析信息

1.3 程序架构设计

程序采用面向对象的设计模式,主要包含以下组件:

  • AdvancedPasswordGenerator类:核心功能类,包含所有生成逻辑

  • 数据加载模块:负责加载常见密码、模式、权重等基础数据

  • 解析模块:处理输入数据并提取有用信息

  • 生成模块:按难度级别生成密码猜测

  • 输出模块:格式化并保存生成结果

二、数据结构设计详解

2.1 核心数据存储结构
2.1.1 类属性设计
复制代码
class AdvancedPasswordGenerator:
    def __init__(self):
        self.common_passwords = self.load_common_passwords()  # 常见密码库
        self.password_patterns = self.load_password_patterns()  # 密码模式库
        self.name_variations = self.load_name_variation_patterns()  # 姓名变体模式
        self.probability_threshold = 0.001  # 概率阈值
        self.context_weights = self.load_context_weights()  # 上下文权重

common_passwords:包含超过200个常见密码的列表,这些密码基于现实世界密码泄露统计数据精心挑选。数据结构采用列表形式,便于快速遍历和匹配。

password_patterns:字典结构,包含多种密码模式:

  • keyboard:键盘相邻键位序列(如"qwerty"、"asdfgh")

  • sequences:数字序列和重复模式(如"123456"、"111111")

  • years:年份范围(1950-2023)

  • common_suffixes:常见后缀(数字、特殊字符、字母组合)

  • common_prefixes:常见前缀

name_variations:专门处理姓名变体的配置字典,包含:

  • separators:姓名组合分隔符(无分隔符、点、下划线、连字符)

  • capitalizations:大小写变换策略(全小写、全大写、首字母大写、混合)

  • leet_subs:leet语替换映射表

context_weights:上下文权重字典,用于在不同生成策略间分配优先级,确保高概率组合优先生成。

2.2 用户数据解析结构
2.2.1 输入数据格式

程序期望的输入数据格式为TSV(制表符分隔值)格式,每行包含一个用户的个人信息,字段格式为"键:值"对,例如:

复制代码
name:John|Doe account:johndoe phone:13800138000 birth:19900101 email:john@example.com
2.2.2 用户数据字典结构

解析后的每个用户数据表示为字典,包含以下关键字段:

复制代码
user_data = {
    'line_number': 1,           # 行号(用于确定难度)
    'difficulty': 'easy',       # 难度等级
    'name': 'John|Doe',         # 原始姓名
    'name_parts': ['John', 'Doe'],  # 分割后的姓名部分
    'first_name': 'John',       # 名字
    'last_name': 'Doe',         # 姓氏
    'middle_names': [],         # 中间名
    'initials': ['J', 'D'],     # 首字母缩写
    'account_clean': 'johndoe', # 清理后的账号
    'phone_clean': '13800138000', # 纯数字电话
    'birth_clean': '19900101',  # 标准化生日
    'birth_year': '1990',       # 年份
    'birth_year_short': '90',   # 两位年份
    'birth_month': '01',        # 月份
    'birth_day': '01',          # 日期
    # 多种日期格式变体
    'email_local': 'john',      # 邮箱本地部分
    'email_domain': 'example.com' # 邮箱域名
}
2.2.3 日期处理逻辑

程序对生日字段进行了全面的格式解析,生成多种常见的日期表示形式:

  • 标准格式:YYYYMMDD, YYYY-MM-DD

  • 短格式:YYMMDD, MMDDYY, DDMMYY

  • 分隔格式:MM/DD/YYYY, DD/MM/YYYY等

这种多格式支持非常重要,因为用户在使用日期作为密码元素时,往往会采用不同的格式习惯。

2.3 密码生成过程中的数据结构
2.3.1 猜测密码存储

生成的密码使用Python集合(set)进行临时存储,确保唯一性,最后转换为列表并排序:

复制代码
guesses = set()  # 临时存储,去重
valid_guesses = []  # 有效密码列表
unique_guesses = list(OrderedDict.fromkeys(valid_guesses))  # 保持顺序的去重
unique_guesses.sort(key=len)  # 按长度排序

使用集合进行中间存储可以有效避免重复项,提高生成效率。最后转换为有序字典再转为列表,既保持了唯一性又维护了生成顺序。

2.3.2 元素组合策略

程序采用组合数学的方法生成密码:

  • 排列组合:使用itertools.permutations生成元素的全排列

  • 笛卡尔积:使用itertools.product处理多字符替换

  • 随机抽样:对于复杂组合,使用random.sample控制生成数量

三、核心算法深入解析

3.1 主控制算法
3.1.1 整体流程控制
复制代码
def process_all_users(self, file_content):
    users = self.parse_user_data(file_content)  # 解析用户数据
    stats = self.analyze_and_optimize(users)   # 统计分析
    results = []
    
    for user in users:
        guesses = self.generate_for_user(user)  # 为每个用户生成密码
        results.append(guesses)
    
    return results

该算法采用分层处理策略,先整体分析数据特征,再针对每个用户个性化生成。这种设计既保证了效率,又确保了个性化生成的准确性。

3.1.2 难度分级算法
复制代码
def determine_difficulty(self, line_num):
    if line_num <= 200:
        return 'easy'
    elif line_num <= 400:
        return 'medium'
    else:
        return 'hard'

基于行号的简单线性分级策略,虽然简单但实用。在实际应用中,这种分级可以基于更复杂的用户属性进行扩展。

3.2 数据解析与清洗算法
3.2.1 个人信息提取算法
复制代码
def extract_personal_elements(self, user_data):
    elements = []
    # 姓名处理
    if user_data.get('first_name'):
        fn = user_data['first_name'].lower()
        elements.extend([fn, fn.capitalize(), fn.upper()])
    # 账号处理
    if user_data.get('account_clean'):
        account = user_data['account_clean']
        elements.append(account)
        # 分割账号中的分隔符
        for sep in ['.', '_', '-']:
            if sep in account:
                elements.extend(account.split(sep))
    return elements

该算法采用多层次的元素提取策略,对每个信息字段生成多种变体形式,确保覆盖用户可能使用的各种格式。

3.2.2 电话号处理算法
复制代码
if user_data.get('phone_clean'):
    phone = user_data['phone_clean']
    if len(phone) >= 4:
        elements.append(phone[-4:])  # 后4位
        elements.append(phone[-5:])  # 后5位
    if len(phone) >= 6:
        elements.append(phone[-6:])  # 后6位

针对电话号码,算法特别关注尾号部分,因为用户更倾向于使用容易记忆的号码末尾部分作为密码元素。

3.3 密码生成算法
3.3.1 普通难度生成算法

普通难度主要采用直接组合策略:

  1. 常见密码直接引用:使用预定义的常见密码库

  2. 个人信息简单使用:直接使用姓名、账号等元素

  3. 基础数字后缀:添加简单的数字序列

  4. 基本特殊字符:在首尾添加单个特殊字符

    def generate_easy_guesses(self, user_data):
    guesses = set()
    guesses.update(self.common_passwords[:300]) # 常见密码

    复制代码
     personal_elements = self.extract_personal_elements(user_data)
     for element in personal_elements:
         if 2 <= len(element) <= 15:
             guesses.add(element)  # 直接使用个人信息
     
     # 简单组合
     if fn and ln:
         for sep in ['', ' ', '.', '_', '-']:
             guesses.add(fn + sep + ln)
3.3.2 中等难度生成算法

中等难度在普通基础上增加:

  1. 多元素组合:两个个人信息元素的排列组合

  2. 年份集成:结合生日年份信息

  3. 复杂数字模式:使用更有意义的数字序列

  4. 基础leet变形:单字符替换

  5. 大小写变形:系统化的大小写变换

    def generate_medium_guesses(self, user_data):
    guesses = self.generate_easy_guesses(user_data)

    复制代码
     # 两元素组合
     for i, elem1 in enumerate(personal_elements[:12]):
         for j, elem2 in enumerate(personal_elements[:12]):
             if i != j:
                 for sep in ['', '.', '_', '-', '']:
                     guesses.add(elem1 + sep + elem2)

算法通过限制元素数量(前12个元素)来控制组合爆炸问题,确保生成效率。

3.3.3 困难难度生成算法

困难难度采用最复杂的生成策略:

  1. 多元素排列:三个及以上元素的排列组合

  2. 高级leet变形:多字符同时替换

  3. 特殊字符集成:在多个位置插入特殊字符

  4. 键盘模式集成:结合键盘相邻键位序列

  5. 反转和重复:密码反转和模式重复

    def generate_hard_guesses(self, user_data):
    guesses = self.generate_medium_guesses(user_data)

    复制代码
     # 三元素组合
     if len(personal_elements) >= 3:
         for combo in itertools.permutations(personal_elements[:8], 3):
             password = ''.join(combo)
             if 5 <= len(password) <= 18:
                 guesses.add(password)

使用itertools.permutations生成排列,通过长度限制确保密码实用性。

3.4 leet语变形算法
3.4.1 基础leet变形
复制代码
def generate_leet_variations(self, base_password):
    variations = set()
    leet_map = {'a': ['4', '@'], 'e': ['3'], ...}
    
    for i, char in enumerate(base_password.lower()):
        if char in leet_map:
            for replacement in leet_map[char]:
                new_pass = base_password[:i] + replacement + base_password[i+1:]
                variations.add(new_pass)
    
    return variations

单点替换策略,每次只替换一个字符,生成所有可能的单字符替换变体。

3.4.2 高级leet变形
复制代码
def generate_advanced_leet_variations(self, base_password):
    variations = set()
    # 单字符替换(同基础版本)
    
    # 多字符替换
    char_positions = [i for i, c in enumerate(base_password.lower()) if c in leet_map]
    if len(char_positions) >= 2:
        for count in [2, 3]:
            if len(char_positions) >= count:
                for positions in itertools.combinations(char_positions[:6], count):
                    for replacements in itertools.product(*[leet_map[base_password[pos].lower()] for pos in positions]):
                        new_pass = list(base_password)
                        for pos, replacement in zip(positions, replacements):
                            new_pass[pos] = replacement
                        variations.add(''.join(new_pass))

使用组合数学方法:

  1. 首先识别所有可替换字符的位置

  2. 选择2-3个位置进行组合

  3. 使用笛卡尔积生成所有可能的替换组合

  4. 限制位置数量(前6个)控制计算复杂度

3.5 概率与权重控制算法
3.5.1 上下文权重系统
复制代码
def load_context_weights(self):
    return {
        'personal_info': 0.35,      # 个人信息权重最高
        'common_patterns': 0.25,     # 常见模式次之
        'keyboard_patterns': 0.15,   # 键盘模式
        'leet_speak': 0.10,          # leet语变形
        'special_chars': 0.08,       # 特殊字符
        'random_combinations': 0.07  # 随机组合
    }

权重系统基于密码心理学研究,反映用户设置密码时的常见偏好。个人信息权重最高,符合"用户倾向使用与自己相关的信息作为密码"的观察结果。

3.5.2 生成数量控制

通过多种机制控制生成数量,避免组合爆炸:

  1. 元素数量限制:只使用前N个元素进行组合

  2. 生成长度限制:密码长度限制在3-20字符

  3. 采样策略:对大型组合空间使用随机采样

  4. 最终截断:每个用户最多生成10000个猜测

四、算法优化与效率分析

4.1 时间复杂度分析
4.1.1 解析阶段复杂度
  • 用户数据解析:O(n),n为用户数量

  • 单个用户解析:O(1),与字段数量成正比但固定

  • 元素提取:O(m),m为字段数量

4.1.2 生成阶段复杂度

普通难度生成复杂度最低,主要取决于个人信息元素数量。中等难度涉及两两组合,复杂度为O(k²),其中k为元素数量。困难难度涉及排列组合,复杂度最高。

通过以下优化控制复杂度:

  1. 元素数量限制:每个难度级别限制使用的元素数量

  2. 组合数量限制:对排列组合进行数量限制

  3. 提前终止:当生成数量接近上限时提前终止

4.2 空间复杂度优化
4.2.1 内存使用优化
  1. 生成时去重:使用集合自动去重,减少内存占用

  2. 分批处理:不是一次性生成所有组合,而是按需生成

  3. 及时清理:在每个用户处理完成后清理临时数据

4.2.2 存储优化

输出时使用OrderedDict保持顺序的同时去重,既减少了存储空间,又维护了生成逻辑的顺序性。

4.3 生成质量评估
4.3.1 密码质量指标

程序通过多种机制确保生成密码的质量:

  1. 长度合理性:限制密码长度在3-20字符,符合实际使用情况

  2. 字符多样性:确保包含字母、数字或特殊字符

  3. 模式真实性:基于真实密码数据分析选择模式

4.3.2 覆盖度评估

通过统计分析模块评估生成策略的有效性:

复制代码
def analyze_and_optimize(self, users):
    stats = {
        'easy_count': 0, 'medium_count': 0, 'hard_count': 0,
        'has_name': 0, 'has_account': 0, 'has_phone': 0,
        'has_birth': 0, 'has_email': 0
    }
    # 统计各种信息的出现频率

这些统计数据可以用于优化生成策略,优先覆盖更常见的模式。

五、程序扩展性与改进方向

5.1 数据驱动的优化
5.1.1 机器学习集成

可以集成机器学习算法来分析密码模式:

  • 使用神经网络学习密码生成模式

  • 基于真实泄露数据训练生成模型

  • 动态调整权重基于用户行为分析

5.1.2 模式学习

实现模式学习功能,让程序能够从成功猜测中学习:

复制代码
def learn_from_success(self, successful_guesses, user_context):
    # 分析成功猜测的模式特征
    # 调整生成策略和权重
5.2 功能扩展方向
5.2.1 多语言支持

扩展对多语言个人信息的支持:

  • 不同语言的姓名处理规则

  • 本地化的日期格式

  • 区域特定的常见密码模式

5.2.2 社交工程扩展

集成社交工程数据:

  • 社交媒体用户名和模式

  • 兴趣爱好相关词汇

  • 家庭成员和宠物信息

5.3 性能优化方向
5.3.1 并行化处理

利用多核处理器进行并行生成:

复制代码
from concurrent.futures import ThreadPoolExecutor

def parallel_generate(self, users):
    with ThreadPoolExecutor() as executor:
        results = list(executor.map(self.generate_for_user, users))
    return results
5.3.2 增量生成

实现增量生成功能,支持中断恢复:

  • 保存生成状态

  • 支持从特定用户继续生成

  • 结果去重和合并

六、安全与伦理考量

6.1 合法使用规范

程序明确设计用于合法目的:

  • 安全测试和评估

  • 数字取证调查

  • 学术研究

6.2 隐私保护机制

在处理包含真实个人信息的数据时:

  • 数据最小化原则

  • 处理完成后及时清理

  • 结果脱敏处理

6.3 责任使用指南

提供明确的使用指南和责任声明,确保用户了解:

  • 合法使用场景

  • 潜在风险

  • 责任限制

七、总结

本高级密码生成器程序是一个功能全面、设计精巧的密码分析工具。它通过多层次的数据解析、智能化的生成策略和系统化的优化控制,实现了高效且有效的密码猜测生成。

程序的核心优势在于:

  1. 系统化的架构设计:模块清晰,职责分明

  2. 数据驱动的生成策略:基于真实密码心理学研究

  3. 可扩展的算法框架:支持后续功能增强和优化

  4. 实用的复杂度控制:在覆盖度和效率间取得良好平衡

该程序不仅是一个实用的安全工具,也为密码行为研究提供了有价值的技术基础。通过进一步集成机器学习和其他先进技术,有望在密码安全领域发挥更大作用。

源代码

复制代码
import re
import itertools
from collections import Counter, OrderedDict
import random
import math


class AdvancedPasswordGenerator:
    def __init__(self):
        self.common_passwords = self.load_common_passwords()
        self.password_patterns = self.load_password_patterns()
        self.name_variations = self.load_name_variation_patterns()
        self.probability_threshold = 0.001
        self.context_weights = self.load_context_weights()

    def load_name_variation_patterns(self):
        """加载姓名变体模式"""
        return {
            'separators': ['', '.', '_', '-', ''],
            'capitalizations': ['lower', 'upper', 'capitalize', 'mixed'],
            'leet_subs': {
                'a': ['4', '@'],
                'e': ['3'],
                'i': ['1', '!'],
                'o': ['0'],
                's': ['5', '$'],
                't': ['7'],
                'l': ['1'],
                'g': ['9'],
                'b': ['8'],
                'z': ['2']
            }
        }

    def load_context_weights(self):
        """加载上下文权重"""
        return {
            'personal_info': 0.35,
            'common_patterns': 0.25,
            'keyboard_patterns': 0.15,
            'leet_speak': 0.10,
            'special_chars': 0.08,
            'random_combinations': 0.07
        }

    def load_common_passwords(self):
        """加载扩展的常见密码列表"""
        common = [
            '123456', 'password', '12345678', 'qwerty', 'abc123',
            '123456789', '111111', '1234567', 'iloveyou', 'admin',
            'welcome', 'monkey', '1234567890', '123123', '000000',
            '12345', '1234', 'sunshine', 'princess', 'letmein',
            'solo', '123456a', 'football', 'qwerty123', 'superman',
            '1qaz2wsx', 'baseball', 'password1', 'master', 'hello',
            'freedom', 'whatever', 'qazwsx', 'trustno1', '654321',
            'jordan23', 'harley', '123qwe', 'michael', 'dragon',
            'mustang', 'shadow', 'ashley', 'bailey', 'blink182',
            '123abc', '1q2w3e4r', 'qwer1234', 'pass123', 'admin123',
            'welcome123', 'login', 'passw0rd', 'abc123456', 'password123',
            '1234qwer', 'qwe123', 'asdf1234', '12345678910', 'qwertyuiop',
            'asdfghjkl', 'zxcvbnm', 'qazwsxedc', '1q2w3e4r5t', '1qaz2wsx3edc',
            'zaq12wsx', '!qaz2wsx', 'qqww1122', 'pass@123', 'p@ssw0rd',
            'admin@123', 'welcome1', 'hello123', 'iloveyou123', 'sunshine1',
            'princess1', 'dragon1', 'superman1', 'master1', 'shadow1',
            'monkey1', 'letmein1', '123456789a', 'a123456', '123456a789',
            'aa123456', '123456abc', 'abc123456789', '123abc456', '1234abcd',
            'abcd1234', '12345678a', 'a12345678', '123456aa', '123456ab',
            'ab123456', '123456abcde', 'abcde12345', '12345abc', 'abc12345',
            '1234abc', 'abc1234', '123abc', 'abc123', '12abc', 'abc12',
            '1abc', 'abc1', '1234asdf', 'asdf1234', 'qwer1234', '1234qwer',
            'zxcv1234', '1234zxcv', '1234!@#$', '!@#$1234', '1234qaz',
            'qaz1234', '1234wsx', 'wsx1234', '1234edc', 'edc1234',
            # 添加更多常见密码
            '123456', '123456789', '12345', '1234567890', '1234567',
            '12345678', '1234', '123', '123456a', '123abc', 'abc123',
            'password1', 'password123', 'qwerty123', '1q2w3e4r', '1qaz2wsx',
            'zaq1xsw2', 'qazwsx', 'qazxsw', '!qaz2wsx', '1qaz@wsx',
            '1qaz#edc', '1qaz$rfv', '1qaz%tgb', '1qaz^yhn', '1qaz&ujm',
            '1qaz*ik,', '1qaz(ol.', '1qaz)p;/', '1qaz)okm', '1qaz(ijn',
            '1qaz*uhb', '1qaz&ygv', '1qaz^tfc', '1qaz%rdx', '1qaz$esz',
            '1qaz@wsx', '1qaz!qaz', '1qaz@wsx#edc', '1qaz@wsx$rfv',
            '1qaz@wsx%tgb', '1qaz@wsx^yhn', '1qaz@wsx&ujm', '1qaz@wsx*ik,',
            '1qaz@wsx(ol.', '1qaz@wsx)p;/', '1qaz@wsx)okm', '1qaz@wsx(ijn',
            '1qaz@wsx*uhb', '1qaz@wsx&ygv', '1qaz@wsx^tfc', '1qaz@wsx%rdx',
            '1qaz@wsx$esz', '1qaz@wsx#qaz', '1qaz@wsx#wsx', '1qaz@wsx#edc',
            '1qaz@wsx#rfv', '1qaz@wsx#tgb', '1qaz@wsx#yhn', '1qaz@wsx#ujm',
            '1qaz@wsx#ik,', '1qaz@wsx#ol.', '1qaz@wsx#p;/', '1qaz@wsx#okm',
            '1qaz@wsx#ijn', '1qaz@wsx#uhb', '1qaz@wsx#ygv', '1qaz@wsx#tfc',
            '1qaz@wsx#rdx', '1qaz@wsx#esz', '1qaz@wsx#qaz', '1qaz@wsx#wsx'
        ]
        return common

    def load_password_patterns(self):
        """加载密码模式"""
        return {
            'keyboard': [
                'qwerty', 'asdfgh', 'zxcvbn', 'qazwsx', '1qaz2wsx',
                'qwer1234', 'zaq12wsx', '!qaz2wsx', '1q2w3e4r',
                'qwerty123', 'asdf1234', 'zxcv1234', 'qazxsw', 'zaq1xsw2',
                '!qaz@wsx', '1qaz@wsx', '1qaz#edc', '1qaz$rfv', '1qaz%tgb',
                '1qaz^yhn', '1qaz&ujm', '1qaz*ik,', '1qaz(ol.', '1qaz)p;/'
            ],
            'sequences': [
                '123', '1234', '12345', '123456', '1234567', '12345678',
                '111', '222', '333', '444', '555', '666', '777', '888', '999',
                '000', '1111', '2222', '3333', '1212', '1122', '1313', '123123',
                '123321', '112233', '12344321', '1234554321', '123456654321',
                '123456789', '987654321', '1234567890', '0987654321'
            ],
            'years': [str(year) for year in range(1950, 2024)],
            'common_suffixes': [
                '123', '1234', '12345', '123456', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
                '!', '@', '#', '$', '%', '&', '*', '00', '01', '10', '11', '12', '13', '88', '99',
                'abc', 'xyz', 'qq', 'ww', 'aa', 'bb', 'cc', 'dd', 'ee', 'ff',
                '000', '111', '222', '333', '444', '555', '666', '777', '888', '999',
                '007', '100', '200', '300', '400', '500', '600', '700', '800', '900'
            ],
            'common_prefixes': [
                'a', 'A', 'abc', 'qq', 'ww', '!', '@', '#', '$', '%', '&', '*'
            ]
        }

    def parse_user_data(self, file_content):
        """增强的用户数据解析"""
        users = []
        lines = file_content.strip().split('\n')

        for line_num, line in enumerate(lines, 1):
            if not line.strip():
                continue

            user_data = {'line_number': line_num, 'difficulty': self.determine_difficulty(line_num)}
            fields = line.split('\t')

            for field in fields:
                if ':' in field:
                    key, value = field.split(':', 1)
                    user_data[key.strip()] = value.strip()

            # 增强姓名解析
            if 'name' in user_data:
                name_parts = user_data['name'].split('|')
                user_data['name_parts'] = [part.strip() for part in name_parts if part.strip()]

                # 提取所有可能的姓名组件
                if name_parts:
                    user_data['first_name'] = name_parts[0].strip()
                    user_data['last_name'] = name_parts[-1].strip() if len(name_parts) > 1 else ''

                    # 提取中间名/缩写
                    user_data['middle_names'] = name_parts[1:-1] if len(name_parts) > 2 else []
                    user_data['initials'] = [name[0] for name in name_parts if name]

            # 清理和标准化数据
            user_data['account_clean'] = user_data.get('account', '').lower().strip()
            user_data['phone_clean'] = re.sub(r'\D', '', user_data.get('phone', ''))
            user_data['birth_clean'] = user_data.get('birth', '')

            # 提取日期组件
            if user_data['birth_clean'] and len(user_data['birth_clean']) == 8:
                birth = user_data['birth_clean']
                user_data['birth_year'] = birth[:4]
                user_data['birth_year_short'] = birth[2:4]
                user_data['birth_month'] = birth[4:6]
                user_data['birth_day'] = birth[6:8]
                user_data['birth_mmddyy'] = birth[4:6] + birth[6:8] + birth[2:4]
                user_data['birth_ddmmyy'] = birth[6:8] + birth[4:6] + birth[2:4]
                user_data['birth_yyyymmdd'] = birth
                user_data['birth_ddmmyyyy'] = birth[6:8] + birth[4:6] + birth[:4]
                user_data['birth_mmddyyyy'] = birth[4:6] + birth[6:8] + birth[:4]

            # 邮箱解析
            if 'email' in user_data:
                email = user_data['email']
                if '@' in email:
                    user_data['email_local'] = email.split('@')[0]
                    user_data['email_domain'] = email.split('@')[1]

            users.append(user_data)

        return users

    def determine_difficulty(self, line_num):
        """根据行号确定难度"""
        if line_num <= 200:
            return 'easy'  # 普通难度
        elif line_num <= 400:
            return 'medium'  # 中等难度
        else:
            return 'hard'  # 困难难度

    def extract_personal_elements(self, user_data):
        """提取所有可能的个人信息元素"""
        elements = []

        # 姓名相关
        if user_data.get('first_name'):
            fn = user_data['first_name'].lower()
            elements.extend([fn, fn.capitalize(), fn.upper()])
            # 姓名变体
            if len(fn) > 3:
                elements.append(fn[:3])
                elements.append(fn[:4])
        if user_data.get('last_name'):
            ln = user_data['last_name'].lower()
            elements.extend([ln, ln.capitalize(), ln.upper()])
            if len(ln) > 3:
                elements.append(ln[:3])
                elements.append(ln[:4])
        if user_data.get('initials'):
            elements.extend(user_data['initials'])
            elements.extend([i.upper() for i in user_data['initials']])
            if len(user_data['initials']) > 1:
                elements.append(''.join(user_data['initials']))
                elements.append(''.join([i.upper() for i in user_data['initials']]))
                # 反转 initials
                elements.append(''.join(user_data['initials'][::-1]))

        # 账号相关
        if user_data.get('account_clean'):
            account = user_data['account_clean']
            elements.append(account)
            # 账号变体
            if '.' in account:
                parts = account.split('.')
                elements.extend(parts)
                elements.append(parts[0])
                if len(parts) > 1:
                    elements.append(parts[1])
            if '_' in account:
                parts = account.split('_')
                elements.extend(parts)
                elements.append(parts[0])
                if len(parts) > 1:
                    elements.append(parts[1])
            if '-' in account:
                parts = account.split('-')
                elements.extend(parts)
                elements.append(parts[0])
                if len(parts) > 1:
                    elements.append(parts[1])

        # 邮箱相关
        if user_data.get('email_local'):
            email_local = user_data['email_local']
            elements.append(email_local)
            if '.' in email_local:
                parts = email_local.split('.')
                elements.extend(parts)

        # 日期相关
        date_fields = ['birth_year', 'birth_year_short', 'birth_month', 'birth_day',
                       'birth_mmddyy', 'birth_ddmmyy', 'birth_yyyymmdd', 'birth_ddmmyyyy', 'birth_mmddyyyy']
        for field in date_fields:
            if user_data.get(field):
                elements.append(user_data[field])

        # 电话相关
        if user_data.get('phone_clean'):
            phone = user_data['phone_clean']
            if len(phone) >= 4:
                elements.append(phone[-4:])
                elements.append(phone[-5:])
            if len(phone) >= 6:
                elements.append(phone[-6:])
                elements.append(phone[-7:])
            if len(phone) == 11:
                elements.append(phone)
                elements.append(phone[3:])
                elements.append(phone[-8:])

        return [e for e in elements if e and len(e) >= 1]

    def generate_easy_guesses(self, user_data):
        """为普通难度用户生成密码猜测"""
        guesses = set()

        # 直接使用常见密码
        guesses.update(self.common_passwords[:300])

        # 直接个人信息
        personal_elements = self.extract_personal_elements(user_data)
        for element in personal_elements:
            if 2 <= len(element) <= 15:
                guesses.add(element)

        # 简单组合
        fn = user_data.get('first_name', '').lower()
        ln = user_data.get('last_name', '').lower()

        if fn and ln:
            # 姓名组合
            for sep in ['', ' ', '.', '_', '-']:
                guesses.add(fn + sep + ln)
                guesses.add(ln + sep + fn)
                guesses.add(fn[0] + sep + ln)
                guesses.add(fn + sep + ln[0])
                guesses.add(fn[0] + ln)
                guesses.add(fn + ln[0])

        # 账号组合
        account = user_data.get('account_clean')
        if account:
            if fn:
                guesses.add(account + fn)
                guesses.add(fn + account)
                guesses.add(account + '.' + fn)
                guesses.add(fn + '.' + account)
            if ln:
                guesses.add(account + ln)
                guesses.add(ln + account)

        # 简单数字后缀
        for base in list(guesses)[:150]:
            for i in range(0, 100):
                guesses.add(base + str(i))
                if i < 10:
                    guesses.add(base + '0' + str(i))
            # 常见数字后缀
            for suffix in ['123', '1234', '1', '2', '11', '12', '13', '00', '01', '10']:
                guesses.add(base + suffix)

        # 简单特殊字符
        for base in list(guesses)[:100]:
            for char in ['!', '@', '#', '$', '%', '&', '*']:
                guesses.add(base + char)
                guesses.add(char + base)

        return guesses

    def generate_medium_guesses(self, user_data):
        """为中等难度用户生成密码猜测"""
        guesses = self.generate_easy_guesses(user_data)

        # 更多个人信息组合
        personal_elements = self.extract_personal_elements(user_data)

        # 两元素组合
        for i, elem1 in enumerate(personal_elements[:12]):
            for j, elem2 in enumerate(personal_elements[:12]):
                if i != j:
                    for sep in ['', '.', '_', '-', '']:
                        combo = elem1 + sep + elem2
                        if 4 <= len(combo) <= 16:
                            guesses.add(combo)

        # 年份组合
        if user_data.get('birth_year'):
            birth_year = user_data['birth_year']
            birth_year_short = user_data.get('birth_year_short', '')

            for base in list(guesses)[:150]:
                guesses.add(base + birth_year)
                guesses.add(base + birth_year_short)
                guesses.add(birth_year + base)
                guesses.add(birth_year_short + base)

        # 更多数字模式
        for base in list(guesses)[:150]:
            for pattern in ['123', '1234', '12345', '111', '222', '333', '000', '007', '100', '200']:
                guesses.add(base + pattern)
                guesses.add(pattern + base)

        # Leet语基础变形
        for base in list(guesses)[:150]:
            if len(base) <= 12:
                leet_variations = self.generate_leet_variations(base)
                guesses.update(leet_variations)

        # 大小写变形
        for base in list(guesses)[:100]:
            if base.isalpha() and len(base) > 2:
                guesses.add(base.capitalize())
                guesses.add(base.upper())
                # 首字母大写变体
                if ' ' in base or '.' in base or '_' in base:
                    parts = re.split(r'[ ._]', base)
                    capitalized = ''.join(part.capitalize() for part in parts if part)
                    guesses.add(capitalized)

        return guesses

    def generate_hard_guesses(self, user_data):
        """为困难难度用户生成密码猜测"""
        guesses = self.generate_medium_guesses(user_data)

        # 复杂个人信息组合
        personal_elements = self.extract_personal_elements(user_data)

        # 三元素组合
        if len(personal_elements) >= 3:
            for combo in itertools.permutations(personal_elements[:8], 3):
                # 无分隔符
                password = ''.join(combo)
                if 5 <= len(password) <= 18:
                    guesses.add(password)

                # 各种分隔符
                for sep in ['.', '_', '-', '']:
                    password = sep.join(combo)
                    if 5 <= len(password) <= 20:
                        guesses.add(password)

        # 四元素组合(限制数量)
        if len(personal_elements) >= 4:
            for i in range(min(50, len(personal_elements) ** 2)):
                combo = random.sample(personal_elements[:6], 4)
                password = ''.join(combo)
                if 6 <= len(password) <= 20:
                    guesses.add(password)

        # 高级Leet语变形
        for base in list(guesses)[:300]:
            if 3 <= len(base) <= 15:
                leet_variations = self.generate_advanced_leet_variations(base)
                guesses.update(leet_variations)

        # 特殊字符变体
        for base in list(guesses)[:200]:
            if 4 <= len(base) <= 16:
                special_chars = ['!', '@', '#', '$', '%', '&', '*']
                # 在开头和末尾添加特殊字符
                for char1 in special_chars:
                    guesses.add(char1 + base)
                    guesses.add(base + char1)
                    for char2 in special_chars:
                        guesses.add(char1 + base + char2)
                        # 在中间插入特殊字符
                        if len(base) > 3:
                            mid = len(base) // 2
                            guesses.add(base[:mid] + char1 + base[mid:])

        # 键盘模式
        for pattern in self.password_patterns['keyboard']:
            guesses.add(pattern)
            # 与个人信息组合
            for base in list(guesses)[:80]:
                guesses.add(base + pattern)
                guesses.add(pattern + base)

        # 反转密码
        for base in list(guesses)[:150]:
            if 3 <= len(base) <= 15:
                guesses.add(base[::-1])

        # 重复模式
        for base in list(guesses)[:100]:
            if 2 <= len(base) <= 8:
                guesses.add(base * 2)
                guesses.add(base * 3)

        return guesses

    def generate_leet_variations(self, base_password):
        """生成基础leet语变形"""
        variations = set()

        leet_map = {
            'a': ['4', '@'],
            'e': ['3'],
            'i': ['1', '!'],
            'o': ['0'],
            's': ['5', '$'],
            't': ['7']
        }

        # 单字符替换
        for i, char in enumerate(base_password.lower()):
            if char in leet_map:
                for replacement in leet_map[char]:
                    new_pass = base_password[:i] + replacement + base_password[i + 1:]
                    variations.add(new_pass)

        return variations

    def generate_advanced_leet_variations(self, base_password):
        """生成高级leet语变形"""
        variations = set()

        leet_map = {
            'a': ['4', '@'],
            'e': ['3'],
            'i': ['1', '!'],
            'o': ['0'],
            's': ['5', '$'],
            't': ['7'],
            'l': ['1'],
            'g': ['9'],
            'b': ['8'],
            'z': ['2']
        }

        # 单字符替换
        for i, char in enumerate(base_password.lower()):
            if char in leet_map:
                for replacement in leet_map[char]:
                    new_pass = base_password[:i] + replacement + base_password[i + 1:]
                    variations.add(new_pass)

        # 多字符替换(最多3个字符)
        if len(base_password) <= 12:
            char_positions = [i for i, c in enumerate(base_password.lower()) if c in leet_map]
            if len(char_positions) >= 2:
                # 选择2-3个位置进行替换
                for count in [2, 3]:
                    if len(char_positions) >= count:
                        for positions in itertools.combinations(char_positions[:6], count):
                            for replacements in itertools.product(
                                    *[leet_map[base_password[pos].lower()] for pos in positions]):
                                new_pass = list(base_password)
                                for pos, replacement in zip(positions, replacements):
                                    new_pass[pos] = replacement
                                variations.add(''.join(new_pass))

        return variations

    def generate_for_user(self, user_data, max_guesses=10000):
        """为单个用户生成密码猜测 - 根据难度调整策略"""
        difficulty = user_data.get('difficulty', 'medium')

        if difficulty == 'easy':
            guesses = self.generate_easy_guesses(user_data)
        elif difficulty == 'medium':
            guesses = self.generate_medium_guesses(user_data)
        else:  # hard
            guesses = self.generate_hard_guesses(user_data)

        # 清理和过滤
        valid_guesses = []
        for guess in guesses:
            if (guess and
                    3 <= len(guess) <= 20 and
                    re.search(r'[a-zA-Z0-9]', guess)):
                valid_guesses.append(guess)

        # 去重并按长度排序
        unique_guesses = list(OrderedDict.fromkeys(valid_guesses))
        unique_guesses.sort(key=len)

        return unique_guesses[:max_guesses]

    def process_all_users(self, file_content):
        """处理所有用户"""
        users = self.parse_user_data(file_content)

        # 分析数据模式
        stats = self.analyze_and_optimize(users)

        results = []
        print(f"\n开始处理 {len(users)} 个用户...")
        print(f"难度分布: 普通(1-200), 中等(201-400), 困难(401-500)")

        for i, user in enumerate(users, 1):
            if i % 50 == 0:
                print(f"已处理 {i}/{len(users)} 个用户 (难度: {user.get('difficulty', 'unknown')})")

            guesses = self.generate_for_user(user)
            results.append(guesses)

        return results

    def analyze_and_optimize(self, users):
        """分析用户数据模式以优化生成策略"""
        stats = {
            'easy_count': 0,
            'medium_count': 0,
            'hard_count': 0,
            'has_name': 0,
            'has_account': 0,
            'has_phone': 0,
            'has_birth': 0,
            'has_email': 0,
            'name_lengths': [],
            'account_lengths': []
        }

        for user in users:
            difficulty = user.get('difficulty', 'unknown')
            if difficulty == 'easy':
                stats['easy_count'] += 1
            elif difficulty == 'medium':
                stats['medium_count'] += 1
            elif difficulty == 'hard':
                stats['hard_count'] += 1

            if user.get('name'):
                stats['has_name'] += 1
                if user.get('first_name'):
                    stats['name_lengths'].append(len(user['first_name']))
            if user.get('account'):
                stats['has_account'] += 1
                stats['account_lengths'].append(len(user['account']))
            if user.get('phone'):
                stats['has_phone'] += 1
            if user.get('birth'):
                stats['has_birth'] += 1
            if user.get('email'):
                stats['has_email'] += 1

        print("数据统计分析:")
        print(f"用户难度分布: 普通({stats['easy_count']}), 中等({stats['medium_count']}), 困难({stats['hard_count']})")
        print(f"有姓名的用户: {stats['has_name']}/{len(users)} ({stats['has_name'] / len(users) * 100:.1f}%)")
        print(f"有账号的用户: {stats['has_account']}/{len(users)} ({stats['has_account'] / len(users) * 100:.1f}%)")
        print(f"有电话的用户: {stats['has_phone']}/{len(users)} ({stats['has_phone'] / len(users) * 100:.1f}%)")
        print(f"有生日的用户: {stats['has_birth']}/{len(users)} ({stats['has_birth'] / len(users) * 100:.1f}%)")
        print(f"有邮箱的用户: {stats['has_email']}/{len(users)} ({stats['has_email'] / len(users) * 100:.1f}%)")

        if stats['name_lengths']:
            avg_name_len = sum(stats['name_lengths']) / len(stats['name_lengths'])
            print(f"平均名字长度: {avg_name_len:.1f}")

        if stats['account_lengths']:
            avg_account_len = sum(stats['account_lengths']) / len(stats['account_lengths'])
            print(f"平均账号长度: {avg_account_len:.1f}")

        return stats

    def save_results(self, results, filename='2.txt'):
        """保存结果到文件"""
        with open(filename, 'w', encoding='utf-8') as f:
            total_guesses = 0
            max_guesses = 0
            min_guesses = float('inf')
            difficulty_counts = {'easy': 0, 'medium': 0, 'hard': 0}

            for i, guesses in enumerate(results, 1):
                for guess in guesses:
                    f.write(guess + '\n')
                f.write('<END>\n')

                total_guesses += len(guesses)
                max_guesses = max(max_guesses, len(guesses))
                min_guesses = min(min_guesses, len(guesses))

                # 统计各难度猜测数
                if i <= 200:
                    difficulty_counts['easy'] += len(guesses)
                elif i <= 400:
                    difficulty_counts['medium'] += len(guesses)
                else:
                    difficulty_counts['hard'] += len(guesses)

        avg_guesses = total_guesses // len(results)

        print(f"\n结果已保存到 {filename}")
        print(f"统计信息:")
        print(f"  用户数量: {len(results)}")
        print(f"  总猜测数: {total_guesses}")
        print(f"  平均每个用户: {avg_guesses} 个猜测")
        print(f"  最多猜测数: {max_guesses}")
        print(f"  最少猜测数: {min_guesses}")
        print(
            f"  各难度猜测数: 普通({difficulty_counts['easy']}), 中等({difficulty_counts['medium']}), 困难({difficulty_counts['hard']})")


def main():
    # 读取数据文件
    try:
        with open('1.txt', 'r', encoding='utf-8') as f:
            file_content = f.read()
    except FileNotFoundError:
        print("错误:找不到 '1.txt' 文件")
        return
    except UnicodeDecodeError:
        # 尝试其他编码
        try:
            with open('1.txt', 'r', encoding='gbk') as f:
                file_content = f.read()
        except:
            print("错误:无法读取文件,请检查文件编码")
            return

    # 生成密码猜测
    generator = AdvancedPasswordGenerator()
    results = generator.process_all_users(file_content)

    # 保存结果
    generator.save_results(results)


if __name__ == "__main__":
    main()
相关推荐
AI科技星2 小时前
时空的固有脉动:波动方程 ∇²L = (1/c²) ∂²L/∂t² 的第一性原理推导、诠释与验证
数据结构·人工智能·算法·机器学习·重构
独自破碎E2 小时前
Leetcode862和至少为K的最短子数组
java·开发语言
qq_370773092 小时前
x64dbg 脚本常用命令
开发语言·x64dbg
阿豪只会阿巴2 小时前
【多喝热水系列】从零开始的ROS2之旅——Day4
c++·笔记·python·ros2
军军君012 小时前
Three.js基础功能学习五:雾与渲染目标
开发语言·前端·javascript·学习·3d·前端框架·three
charlie1145141912 小时前
FreeRTOS:软件定时器(Software Timers)与时间管理
开发语言·笔记·学习·freertos·实时操作系统·工程
2401_841495642 小时前
【LeetCode刷题】寻找重复数
数据结构·python·算法·leetcode·链表·数组·重复数
laplace01232 小时前
LangChain 1.0 入门实战(Part 1)详细笔记
笔记·python·langchain·numpy·pandas
washingtin2 小时前
Get “https://registry-1.docker.io/v2/“: context deadline exceeded
java·开发语言