一、程序概述与功能分析
1.1 程序定位与应用场景
本程序是一个高级密码生成器,专门设计用于生成基于用户个人信息的密码猜测组合。该工具主要应用于以下场景:
-
安全测试与渗透测试:帮助安全专业人员评估系统密码强度
-
数字取证调查:协助执法部门恢复或猜测嫌疑人的密码
-
用户行为研究:分析用户设置密码的常见模式和习惯
-
密码策略评估:验证组织密码策略的有效性
1.2 核心功能特点
程序具备以下核心功能:
-
智能数据解析:能够解析包含多种个人信息字段的输入数据
-
分层难度系统:根据用户数据所在行号自动划分难度等级(普通/中等/困难)
-
多策略生成:针对不同难度级别采用不同的密码生成策略
-
上下文感知:结合个人信息、常见模式、键盘模式等多种元素
-
leet语变形:支持字符替换的高级密码变形技术
-
统计分析:提供生成过程的详细统计和分析信息
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 普通难度生成算法
普通难度主要采用直接组合策略:
-
常见密码直接引用:使用预定义的常见密码库
-
个人信息简单使用:直接使用姓名、账号等元素
-
基础数字后缀:添加简单的数字序列
-
基本特殊字符:在首尾添加单个特殊字符
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 中等难度生成算法
中等难度在普通基础上增加:
-
多元素组合:两个个人信息元素的排列组合
-
年份集成:结合生日年份信息
-
复杂数字模式:使用更有意义的数字序列
-
基础leet变形:单字符替换
-
大小写变形:系统化的大小写变换
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 困难难度生成算法
困难难度采用最复杂的生成策略:
-
多元素排列:三个及以上元素的排列组合
-
高级leet变形:多字符同时替换
-
特殊字符集成:在多个位置插入特殊字符
-
键盘模式集成:结合键盘相邻键位序列
-
反转和重复:密码反转和模式重复
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))
使用组合数学方法:
-
首先识别所有可替换字符的位置
-
选择2-3个位置进行组合
-
使用笛卡尔积生成所有可能的替换组合
-
限制位置数量(前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 生成数量控制
通过多种机制控制生成数量,避免组合爆炸:
-
元素数量限制:只使用前N个元素进行组合
-
生成长度限制:密码长度限制在3-20字符
-
采样策略:对大型组合空间使用随机采样
-
最终截断:每个用户最多生成10000个猜测
四、算法优化与效率分析
4.1 时间复杂度分析
4.1.1 解析阶段复杂度
-
用户数据解析:O(n),n为用户数量
-
单个用户解析:O(1),与字段数量成正比但固定
-
元素提取:O(m),m为字段数量
4.1.2 生成阶段复杂度
普通难度生成复杂度最低,主要取决于个人信息元素数量。中等难度涉及两两组合,复杂度为O(k²),其中k为元素数量。困难难度涉及排列组合,复杂度最高。
通过以下优化控制复杂度:
-
元素数量限制:每个难度级别限制使用的元素数量
-
组合数量限制:对排列组合进行数量限制
-
提前终止:当生成数量接近上限时提前终止
4.2 空间复杂度优化
4.2.1 内存使用优化
-
生成时去重:使用集合自动去重,减少内存占用
-
分批处理:不是一次性生成所有组合,而是按需生成
-
及时清理:在每个用户处理完成后清理临时数据
4.2.2 存储优化
输出时使用OrderedDict保持顺序的同时去重,既减少了存储空间,又维护了生成逻辑的顺序性。
4.3 生成质量评估
4.3.1 密码质量指标
程序通过多种机制确保生成密码的质量:
-
长度合理性:限制密码长度在3-20字符,符合实际使用情况
-
字符多样性:确保包含字母、数字或特殊字符
-
模式真实性:基于真实密码数据分析选择模式
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 责任使用指南
提供明确的使用指南和责任声明,确保用户了解:
-
合法使用场景
-
潜在风险
-
责任限制
七、总结
本高级密码生成器程序是一个功能全面、设计精巧的密码分析工具。它通过多层次的数据解析、智能化的生成策略和系统化的优化控制,实现了高效且有效的密码猜测生成。
程序的核心优势在于:
-
系统化的架构设计:模块清晰,职责分明
-
数据驱动的生成策略:基于真实密码心理学研究
-
可扩展的算法框架:支持后续功能增强和优化
-
实用的复杂度控制:在覆盖度和效率间取得良好平衡
该程序不仅是一个实用的安全工具,也为密码行为研究提供了有价值的技术基础。通过进一步集成机器学习和其他先进技术,有望在密码安全领域发挥更大作用。
源代码
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()