一、功能概述
1.1 程序核心功能
AdvancedPasswordGenerator是一个高级密码猜测生成器,主要功能是根据用户提供的个人信息数据,生成可能的密码组合。该程序采用分层策略,针对不同难度的用户生成相应复杂度的密码猜测。
1.2 主要应用场景
-
安全测试:用于评估系统密码策略的安全性
-
密码恢复:辅助用户找回遗忘的密码
-
安全审计:检查用户密码设置的弱点
-
学术研究:分析密码设置模式和用户行为
1.3 功能模块划分
程序主要包含以下功能模块:
-
数据加载与初始化模块
-
用户数据解析模块
-
密码生成策略模块
-
模式分析与优化模块
-
结果输出与统计模块
二、数据结构设计
2.1 核心数据结构
2.1.1 类属性结构
class AdvancedPasswordGenerator:
def __init__(self):
self.common_passwords = [] # 常见密码列表
self.password_patterns = {} # 密码模式字典
self.name_variations = {} # 姓名变体模式
self.probability_threshold = 0.001 # 概率阈值
self.context_weights = {} # 上下文权重
2.1.2 用户数据结构
每个用户数据被解析为包含以下字段的字典:
-
基础信息:line_number, difficulty, name, account, phone, birth, email
-
解析后的组件:name_parts, first_name, last_name, middle_names, initials
-
标准化数据:account_clean, phone_clean, birth_clean
-
日期组件:birth_year, birth_month, birth_day等多种格式
-
邮箱组件:email_local, email_domain
2.2 数据存储结构
2.2.1 密码模式存储
程序使用嵌套字典结构存储各种密码模式:
password_patterns = {
'keyboard': ['qwerty', 'asdfgh', ...], # 键盘模式
'sequences': ['123', '1234', ...], # 数字序列
'years': ['1950', '1951', ...], # 年份
'common_suffixes': ['123', '!', ...], # 常见后缀
'common_prefixes': ['a', 'A', ...] # 常见前缀
}
2.2.2 姓名变体模式
name_variations = {
'separators': ['', '.', '_', '-'], # 分隔符
'capitalizations': ['lower', 'upper', ...], # 大小写变换
'leet_subs': { # Leet语替换
'a': ['4', '@'],
'e': ['3'],
# ... 其他字符映射
}
}
三、算法设计与实现
3.1 用户数据解析算法
3.1.1 数据预处理流程
def parse_user_data(self, file_content):
users = []
lines = file_content.strip().split('\n')
for line_num, line in enumerate(lines, 1):
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()
# 增强解析逻辑
self.enhanced_parsing(user_data)
users.append(user_data)
return users
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 len(fn) > 3:
elements.append(fn[:3])
elements.append(fn[:4])
# 账号相关元素
if user_data.get('account_clean'):
account = user_data['account_clean']
elements.append(account)
if '.' in account:
parts = account.split('.')
elements.extend(parts)
# 日期相关元素
date_fields = ['birth_year', 'birth_year_short', ...]
for field in date_fields:
if user_data.get(field):
elements.append(user_data[field])
return [e for e in elements if e and len(e) >= 2]
3.3 密码生成策略算法
3.3.1 分层生成策略
程序采用三级分层策略,对应不同难度的用户:
第一层:普通难度策略
def generate_easy_guesses(self, user_data):
guesses = set()
# 1. 直接使用常见密码
guesses.update(self.common_passwords[:300])
# 2. 直接个人信息
personal_elements = self.extract_personal_elements(user_data)
for element in personal_elements:
if 3 <= len(element) <= 12:
guesses.add(element)
# 3. 简单组合策略
self.simple_combinations(guesses, user_data)
# 4. 数字后缀策略
self.number_suffix_strategy(guesses)
return guesses
第二层:中等难度策略
在普通难度基础上增加:
-
两元素组合
-
年份组合
-
基础Leet语变形
-
大小写变形
第三层:困难难度策略
在中等难度基础上增加:
-
三元素组合
-
高级Leet语变形
-
特殊字符变体
-
键盘模式组合
-
密码反转
3.3.2 组合生成算法
def generate_combinations(self, elements, num_elements, separators):
"""生成元素组合"""
combinations = set()
# 排列组合
for combo in itertools.permutations(elements[:8], num_elements):
# 无分隔符组合
password = ''.join(combo)
if 5 <= len(password) <= 18:
combinations.add(password)
# 带分隔符组合
for sep in separators:
password = sep.join(combo)
if 5 <= len(password) <= 20:
combinations.add(password)
return combinations
3.4 Leet语变形算法
3.4.1 基础Leet变形
def generate_leet_variations(self, base_password):
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
3.4.2 高级Leet变形
def generate_advanced_leet_variations(self, base_password):
variations = self.generate_leet_variations(base_password)
leet_map = { ... } # 扩展的映射表
# 多字符替换(最多2个字符)
if len(base_password) <= 10:
char_positions = [i for i, c in enumerate(base_password.lower())
if c in leet_map]
if len(char_positions) >= 2:
# 选择2个位置进行替换
for pos1, pos2 in itertools.combinations(char_positions[:4], 2):
for rep1 in leet_map[base_password[pos1].lower()]:
for rep2 in leet_map[base_password[pos2].lower()]:
new_pass = list(base_password)
new_pass[pos1] = rep1
new_pass[pos2] = rep2
variations.add(''.join(new_pass))
return variations
3.5 模式分析与优化算法
3.5.1 统计分析算法
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')
stats[f'{difficulty}_count'] += 1
# 信息完备性统计
for field in ['name', 'account', 'phone', 'birth', 'email']:
if user.get(field):
stats[f'has_{field}'] += 1
# 长度统计
if user.get('first_name'):
stats['name_lengths'].append(len(user['first_name']))
if user.get('account'):
stats['account_lengths'].append(len(user['account']))
return stats
3.5.2 优化策略
基于统计分析结果,程序可以动态调整生成策略:
-
根据姓名平均长度调整截断策略
-
根据信息完备性调整组合复杂度
-
根据难度分布调整资源分配
四、算法复杂度分析
4.1 时间复杂度
4.1.1 主要操作复杂度
-
数据解析:O(n),其中n为用户数量
-
元素提取:O(k),其中k为单个用户的字段数量
-
密码生成:
-
普通难度:O(m²),m为个人信息元素数量
-
中等难度:O(m³)
-
困难难度:O(m⁴)
-
4.1.2 最坏情况分析
在最坏情况下(困难难度用户,大量个人信息元素),组合爆炸可能导致时间复杂度达到O(m,但通过限制元素数量(如只取前8个元素)将复杂度控制在可接受范围内。
4.2 空间复杂度
4.2.1 内存使用分析
-
基础数据存储:O(1),预加载的密码模式占用固定空间
-
用户数据存储:O(n×k),n为用户数量,k为平均字段数量
-
密码猜测存储:O(p),p为生成的密码数量,通过集合去重优化
五、创新性与优化策略
5.1 创新性设计
5.1.1 分层难度适应
程序根据用户行号自动分配难度等级,实现了个性化的密码生成策略,这是传统密码生成器所不具备的智能特性。
5.1.2 多维度信息融合
程序不仅使用基本的个人信息,还通过多种方式解析和组合数据:
-
日期多格式解析(8种不同格式)
-
姓名多组件提取(名字、姓氏、中间名、首字母)
-
层级式组合策略(单元素→双元素→三元素)
5.1.3 智能模式识别
通过统计分析用户数据特征,程序能够识别数据模式并相应调整生成策略,体现了自适应学习的思想。
5.2 优化策略
5.2.1 性能优化
-
集合去重:使用set自动去重,避免重复计算
-
提前截断:对长序列进行长度限制,避免无效组合
-
懒加载:按需生成密码变体,减少内存占用
5.2.2 质量优化
-
长度过滤:只生成3-20字符的有效密码
-
内容验证:确保密码包含字母或数字
-
模式优先级:常见模式优先生成,提高命中率
5.2.3 可扩展性设计
-
模块化架构:各功能模块独立,便于扩展
-
配置化参数:关键参数可调整,适应不同场景
-
插件式模式:密码模式可轻松添加新规则
六、应用价值与局限性
6.1 应用价值
6.1.1 安全评估价值
该程序可用于:
-
评估密码策略的有效性
-
发现密码设置中的常见模式
-
提高系统安全性设计
6.1.2 用户体验研究
通过分析生成的密码模式,可以:
-
了解用户密码设置习惯
-
优化密码策略建议
-
提高密码记忆性研究
6.2 局限性及改进方向
6.2.1 当前局限性
-
规则依赖性:过度依赖预定义模式,可能错过新兴模式
-
文化适应性:姓名解析主要针对西方命名习惯
-
性能瓶颈:大规模数据下可能遇到性能问题
6.2.2 改进方向
-
机器学习集成:引入ML算法识别新模式
-
多文化支持:增加对不同命名习惯的支持
-
分布式计算:支持大规模数据并行处理
七、总结
AdvancedPasswordGenerator是一个设计精巧、功能全面的密码生成系统,其核心价值在于将传统的密码生成技术与现代的数据分析思想相结合。通过分层策略、多维度信息融合和智能模式识别,程序能够高效地生成针对性强、覆盖面广的密码猜测。
程序的数据结构设计合理,算法实现考虑了性能和质量的平衡,创新性的难度自适应机制使其在不同场景下都能保持良好的效果。虽然存在一定的局限性,但通过持续的优化和扩展,有望成为密码安全领域的重要工具。
该程序不仅具有实际应用价值,也为密码学研究和用户行为分析提供了宝贵的数据支持,是密码安全领域一个值得深入研究和发展的方向。
源代码
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',
'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']]))
# 账号相关
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 user_data.get('email_local'):
email_local = user_data['email_local']
elements.append(email_local)
# 日期相关
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:])
if len(phone) >= 6:
elements.append(phone[-6:])
if len(phone) == 11:
elements.append(phone)
elements.append(phone[3:])
return [e for e in elements if e and len(e) >= 2]
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 3 <= len(element) <= 12:
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])
# 账号组合
account = user_data.get('account_clean')
if account:
if fn:
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)
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)
# 更多数字模式
for base in list(guesses)[:150]:
for pattern in ['123', '1234', '12345', '111', '222', '333', '000', '007', '100', '200']:
guesses.add(base + pattern)
# 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)
# 高级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)
# 键盘模式
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])
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)
# 多字符替换(最多2个字符)
if len(base_password) <= 10:
char_positions = [i for i, c in enumerate(base_password.lower()) if c in leet_map]
if len(char_positions) >= 2:
# 选择2个位置进行替换
for pos1, pos2 in itertools.combinations(char_positions[:4], 2):
for rep1 in leet_map[base_password[pos1].lower()]:
for rep2 in leet_map[base_password[pos2].lower()]:
new_pass = list(base_password)
new_pass[pos1] = rep1
new_pass[pos2] = rep2
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()