基于Python的高级密码生成器程序详细分析

一、功能概述

本程序是一个基于Python的高级密码生成器,专门设计用于根据用户个人信息生成可能的密码猜测。该程序综合运用了多种密码生成策略,包括基于常见密码模式、键盘序列、个人信息组合、leet变换(字符替换)、大小写变体等先进技术。程序的核心思想是模拟攻击者在进行定向密码猜测时可能采用的策略,特别是借鉴了TarGuess-I模型的方法论。

1.1 主要功能特点

1.1.1 多源数据解析能力

程序能够处理包含用户个人信息的文本文件,解析姓名、账号、生日、电话号码等多种信息,并进行标准化处理。这种多维度数据采集为后续的密码生成提供了丰富的素材。

1.1.2 多层次密码生成策略

程序实现了从简单到复杂的多层级密码生成方法:

  • 基础常见密码直接使用

  • 基于键盘模式的序列生成

  • 个人信息组合与变形

  • 高级leet变换技术

  • 上下文敏感的智能猜测

1.1.3 智能化优化与排序

生成的密码会经过优先级排序,将更可能被用户使用的密码排列在前面,提高猜测效率。

1.1.4 批量处理能力

程序可以同时处理大量用户数据,为每个用户生成定制化的密码列表。

二、程序架构与类设计

2.1 AdvancedPasswordGenerator类

程序的核心是一个名为AdvancedPasswordGenerator的类,该类封装了所有的密码生成逻辑。这种面向对象的设计使得代码结构清晰,功能模块化,便于维护和扩展。

2.1.1 初始化方法(init)

在初始化过程中,程序加载了多种密码生成所需的资源:

  • 常见密码列表

  • 密码模式库

  • 姓名变体模式

  • 特殊字符集合

  • TarGuess-I策略参数

这种预先加载的方式提高了程序运行时的效率,避免了重复的文件读取操作。

2.2 数据结构设计

2.2.1 用户数据表示

程序使用字典结构来表示每个用户的个人信息,这种键值对的设计既灵活又高效。用户数据结构包含:

user_data = {
    'line_number': 行号,
    'name': 原始姓名,
    'name_parts': 分割后的姓名部分,
    'first_name': 名,
    'last_name': 姓,
    'middle_names': 中间名列表,
    'initials': 首字母列表,
    'all_initials': 所有首字母组合,
    'account_clean': 清理后的账号,
    'email_local': 邮箱本地部分,
    'phone_clean': 清理后的电话,
    'birth_clean': 生日字符串,
    # 多种日期格式分解
    'birth_year': 出生年份,
    'birth_year_short': 短格式年份,
    # 电话部分分解
    'phone_last4': 电话后4位,
    # ... 其他字段
}

这种详细的数据结构使得程序能够从多个维度利用用户信息进行密码生成。

2.2.2 密码模式库

程序维护了一个丰富的密码模式库,包括:

键盘模式:模拟常见的键盘行走模式,如"qwerty"、"asdfgh"等。这些模式反映了用户在设置密码时可能使用的简单序列。

数字序列:包括连续数字("123")、重复数字("111")等常见模式。

时间相关模式:年份信息(1950-2023),反映了用户使用出生年份或其他重要年份作为密码的倾向。

常见前后缀:密码中常见的添加物,如"123"、"!"等,用于增强简单密码的复杂性。

三、核心算法详解

3.1 用户数据解析算法

parse_user_data方法是程序的数据预处理阶段,其算法流程如下:

3.1.1 数据清洗与标准化
  • 去除空白字符和无效数据

  • 统一大小写处理(特别是账号信息)

  • 提取关键信息(如邮箱本地部分)

3.1.2 结构化信息提取

程序对原始数据进行深度解析,特别是对姓名和日期信息的处理:

姓名解析算法

  1. 使用管道符(|)分割姓名字段

  2. 提取名(first_name)、姓(last_name)

  3. 处理中间名和缩写

  4. 生成所有可能的姓名变体

日期解析算法

  1. 标准化日期格式(假设为YYYYMMDD)

  2. 提取年、月、日各个组件

  3. 生成多种日期格式组合(MMDDYY, DDMMYY等)

  4. 这些格式反映了用户可能使用的不同日期表示方式

电话处理算法

  1. 去除非数字字符

  2. 提取前3位、后4位、后6位等有意义的子串

  3. 这些部分常被用户用作密码的组成部分

3.2 Leet变换算法

apply_leet_transform方法实现了高级的字符替换技术,其算法基于强度参数分为三个层次:

3.2.1 基础替换(强度≥0.3)

实现单字符的简单替换,如:

  • a → 4, @

  • e → 3

  • i → 1, !

  • o → 0

这种替换保持了密码的可读性同时增加了复杂性。

3.2.2 中级替换(强度≥0.6)

实现多字符协同替换,如同时替换"a"和"e"为"4"和"3"。这种替换更系统地模拟了用户的leet使用习惯。

3.2.3 高级替换(强度≥0.8)

针对常见单词进行整体替换,如:

  • love → l0v3

  • admin → 4dm1n

  • password → p4ssw0rd

这种单词级的leet变换反映了高级用户的密码设置行为。

算法使用集合来存储结果,确保唯一性,同时考虑了大小写变体。

3.3 大小写变体生成算法

generate_capitalization_variants方法生成字符串的各种大小写形式:

3.3.1 基础变体
  • 原样保留

  • 全小写

  • 全大写

  • 首字母大写

3.3.2 高级变体

驼峰式处理:当检测到分隔符(空格、点、下划线、连字符)时,生成驼峰式变体:

  • 小驼峰:firstName

  • 大驼峰:FirstName

随机大小写:对短字符串(≤8字符)生成随机大小写组合,模拟用户随意设置的大小写模式。

3.4 TarGuess-I策略算法

apply_targess_strategy方法是程序的核心之一,实现了基于TarGuess-I模型的定向猜测策略:

3.4.1 个人信息组件提取

算法从用户数据中提取5类关键信息:

  • 名(first_name)

  • 姓(last_name)

  • 账号本地部分(email_local)

  • 短格式出生年份(birth_year_short)

  • 电话后4位(phone_last4)

3.4.2 组合规则应用

程序预定义了8种个人信息组合方式,如:

  • 名+姓

  • 姓+名

  • 名+电话后4位

  • 电话后4位+名

  • 名+出生年份

  • 出生年份+名

  • 账号+名

  • 名+账号

对于每种组合,应用4种分隔符(无分隔符、点、下划线、连字符)进行连接。

3.4.3 变体生成

对每个基础组合:

  1. 应用大小写变体

  2. 应用leet变换(中等强度0.4)

  3. 添加14种常见后缀模式(如"1", "123", "!"等)

3.5 上下文敏感猜测算法

generate_context_sensitive_guesses方法实现了更智能的密码生成策略:

3.5.1 多维度信息整合

算法将用户信息分为三类:

  • 个人信息(姓名、缩写、账号)

  • 日期信息(多种格式的生日表示)

  • 电话信息(后4位、后6位等)

3.5.2 智能组合策略

策略1:个人信息优先组合

对前3个个人信息元素进行两两组合,应用4种分隔符,并添加日期或电话后缀。

策略2:姓名+数字模式

将姓名与15种常见数字模式组合,如"123", "111"等。

策略3:键盘模式与个人信息结合

将键盘行走模式与个人信息组合,增加密码的随机性。

策略4:智能特殊字符插入

不在简单地在密码两端添加特殊字符,而是在特定位置(开头、中间、结尾附近)插入,模拟用户的实际设置习惯。

3.6 密码优先级排序算法

password_priority函数实现了生成密码的智能排序:

3.6.1 多因素评分系统

算法基于以下因素为每个密码评分:

长度优先级

  • 6-10字符:+50分(最优长度)

  • <6字符:+30分

  • 10字符:+10分

内容类型优先级

  • 纯数字:+40分(常见于简单密码)

  • 字母数字组合:+30分

个人信息相关性

  • 包含名:+25分

  • 包含姓:+25分

  • 包含账号:+20分

  • 包含生日信息:+15分

  • 包含电话信息:+15分

复杂度优先级

  • 特殊字符≤1个:+10分(反映用户偏向简单修改)

四、算法优化与性能考虑

4.1 集合去重技术

程序广泛使用集合(Set)来存储中间结果,利用集合的自动去重特性避免重复计算,提高效率。

4.2 生成限制策略

为了避免生成过多无效密码,程序实施了多种限制:

  • 长度限制(3-20字符)

  • 内容要求(必须包含字母或数字)

  • 最大生成数量限制(默认20000个/用户)

4.3 分层生成策略

程序采用分层生成策略,优先生成高概率密码:

  1. 核心混合策略生成

  2. 扩展组合(数字、特殊字符、年份)

  3. 模式填充(键盘序列、数字序列)

这种策略确保在资源有限的情况下优先生成最有可能的密码。

五、数据处理流程

5.1 完整处理流程

  1. 数据读取:从1.txt文件读取用户数据,支持UTF-8和GBK编码

  2. 数据解析:解析每条用户记录,提取结构化信息

  3. 统计分析:分析用户数据特征,优化生成策略

  4. 密码生成:为每个用户应用多种策略生成密码

  5. 结果优化:去重、排序、过滤无效密码

  6. 结果保存:将密码写入2.txt文件,用<END>分隔不同用户的结果

5.2 批量处理优化

程序实现了批量用户处理功能,每处理50个用户输出进度信息,方便监控大规模数据处理。

六、应用场景与安全意义

6.1 合法应用场景

  1. 密码强度评估:帮助用户评估自己的密码是否容易受到定向猜测攻击

  2. 安全测试:在授权的前提下进行系统安全测试

  3. 安全意识教育:展示基于个人信息的密码猜测技术,提高用户安全意识

6.2 安全意义

本程序演示的密码生成技术反映了现实世界中攻击者可能使用的方法,强调了以下安全原则:

  1. 避免使用个人信息:姓名、生日、电话等个人信息不应直接或简单变形后用作密码

  2. 使用复杂密码:密码应包含多种字符类型,避免常见模式

  3. 使用密码管理器:为不同账户生成并存储随机强密码

七、改进方向与扩展性

7.1 可能的改进

  1. 机器学习集成:引入机器学习模型学习用户的密码设置模式

  2. 多语言支持:扩展对非英语姓名的处理能力

  3. 实时反馈:提供密码强度实时评估功能

  4. 模式学习:从已知密码泄露数据中学习新的密码模式

7.2 扩展性设计

程序的模块化设计使得扩展新功能变得容易:

  • 新的密码生成策略可以作为独立方法添加

  • 用户数据解析可以扩展新的字段类型

  • 排序算法可以引入新的优先级因素

八、总结

本程序是一个功能丰富、算法先进的高级密码生成器,综合运用了多种密码学和社会工程学原理。其核心价值在于展示了基于个人信息的定向密码猜测技术,从防御角度提供了有价值的安全参考。程序的设计体现了良好的软件工程实践,包括模块化、可扩展性和效率优化。

通过深度分析用户个人信息并应用多种变换策略,程序能够生成高度个性化的密码猜测列表,这对于理解密码安全性和提高防护意识具有重要意义。同时,程序也提醒我们,在数字时代保护个人信息的重要性,以及使用强密码的必要性。

源代码

import re
import itertools
from collections import Counter, OrderedDict
import random
import hashlib
from datetime import datetime


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.special_chars = ['!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '-', '_', '+', '=', '.', ',', '?']

        # TarGuess-I 策略参数
        self.targess_rules = self.load_targess_rules()

    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', '123qwe', '1q2w3e4r', 'qwer1234', 'pass123',
            'admin123', 'welcome123', 'login', 'passw0rd', 'abc123456',
            'password123', '1234qwer', '12345a', 'qwe123', 'asdf1234',
            '12345678910', '123456789a', 'qweasdzxc', '1q2w3e4r5t',
            '123321', '123456abc', 'abcd1234', '1234abcd', '1234asdf',
            'qwerasdf', 'zxcvbnm', 'qazxsw', 'zaq12wsx', '!@#$%^&*',
            'pass@123', 'admin@123', 'welcome1', 'password12'
        ]
        return common

    def load_password_patterns(self):
        """加载密码模式"""
        return {
            'keyboard': ['qwerty', 'asdfgh', 'zxcvbn', 'qazwsx', '1qaz2wsx', 'qweasd', '123qwe'],
            'sequences': ['123', '1234', '12345', '123456', '111', '222', '333', '444', '555', '666', '777', '888',
                          '999', '000'],
            'years': [str(year) for year in range(1950, 2024)],
            'common_suffixes': ['123', '1234', '!', '@', '#', '1', '2', '00', '01', '10', '11', '12', '13', '88', '99',
                                '100'],
            'common_prefixes': ['a', 'A', '1', '!', '@', '#', 'qq', 'QQ', 'aa', 'AA']
        }

    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', '6']
            }
        }

    def load_targess_rules(self):
        """加载TarGuess-I模型规则"""
        return {
            'personal_info_combinations': [
                # (first_name, last_name, account, birth_year, phone_tail)
                [0, 1],  # fn + ln
                [1, 0],  # ln + fn
                [0, 4],  # fn + phone_tail
                [4, 0],  # phone_tail + fn
                [0, 3],  # fn + birth_year
                [3, 0],  # birth_year + fn
                [2, 0],  # account + fn
                [0, 2],  # fn + account
            ],
            'separators': ['', '.', '_', '-'],
            'suffix_patterns': [
                '', '1', '12', '123', '1234', '!', '@', '#',
                '123!', '!123', '2023', '23', '2024', '24'
            ]
        }

    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}
            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['all_initials'] = ''.join(user_data['initials'])

            # 清理和标准化数据
            user_data['account_clean'] = user_data.get('account', '').lower().strip()

            # 邮箱账号处理
            if '@' in user_data['account_clean']:
                user_data['email_local'] = user_data['account_clean'].split('@')[0]
            else:
                user_data['email_local'] = user_data['account_clean']

            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_yymmdd'] = birth[2:4] + birth[4:6] + birth[6:8]
                user_data['birth_md'] = birth[4:6] + birth[6:8]  # 月日
                user_data['birth_dm'] = birth[6:8] + birth[4:6]  # 日月

            # 电话处理
            if user_data['phone_clean']:
                phone = user_data['phone_clean']
                user_data['phone_last4'] = phone[-4:] if len(phone) >= 4 else phone
                user_data['phone_last6'] = phone[-6:] if len(phone) >= 6 else phone
                user_data['phone_first3'] = phone[:3] if len(phone) >= 3 else phone

            users.append(user_data)

        return users

    def apply_leet_transform(self, text, intensity=1.0):

        result = set()
        result.add(text)

        if intensity < 0.3:
            return result

        leet_map = self.name_variations['leet_subs']

        # 基础单字符替换
        for char, replacements in leet_map.items():
            if char in text.lower():
                for replacement in replacements:
                    new_text = text.lower().replace(char, replacement)
                    result.add(new_text)
                    # 首字母大写版本
                    if new_text:
                        result.add(new_text.capitalize())

        # 中等强度:选择性多字符替换
        if intensity >= 0.6:
            transformations = [
                (['a', 'e'], ['4', '3']),
                (['a', 's'], ['4', '5']),
                (['e', 't'], ['3', '7']),
                (['o', 's'], ['0', '5']),
            ]

            for chars, replacements in transformations:
                if all(c in text.lower() for c in chars):
                    new_text = text.lower()
                    for i, char in enumerate(chars):
                        new_text = new_text.replace(char, replacements[i])
                    result.add(new_text)
                    if new_text:
                        result.add(new_text.capitalize())

        # 高强度:模式替换
        if intensity >= 0.8:
            # 常见单词的leet变体
            common_leet_words = {
                'love': 'l0v3',
                'admin': '4dm1n',
                'password': 'p4ssw0rd',
                'hello': 'h3ll0',
                'master': 'm4st3r',
                'super': 'sup3r',
                'hacker': 'h4ck3r'
            }

            for word, leet_version in common_leet_words.items():
                if word in text.lower():
                    new_text = text.lower().replace(word, leet_version)
                    result.add(new_text)
                    if new_text:
                        result.add(new_text.capitalize())

        return result

    def generate_capitalization_variants(self, text):
        """生成大小写变体"""
        variants = set()
        if not text:
            return variants

        variants.add(text)
        variants.add(text.lower())
        variants.add(text.upper())
        variants.add(text.capitalize())

        # 驼峰式(如果包含分隔符)
        if any(sep in text for sep in [' ', '.', '_', '-']):
            parts = re.split(r'[ ._-]', text)
            if len(parts) > 1:
                camel_case = parts[0].lower() + ''.join(part.capitalize() for part in parts[1:])
                variants.add(camel_case)

                # 首字母大写驼峰
                pascal_case = ''.join(part.capitalize() for part in parts)
                variants.add(pascal_case)

        # 随机大小写(生成几个随机变体)
        if len(text) <= 8:
            for _ in range(2):
                random_case = ''.join(random.choice([c.upper(), c.lower()]) for c in text)
                variants.add(random_case)

        return variants

    def apply_targess_strategy(self, user_data):
        """应用TarGuess-I定向猜测策略"""
        guesses = set()

        # 提取个人信息组件
        components = []

        # 0: first_name
        fn = user_data.get('first_name', '').lower()
        if fn:
            components.append(fn)

        # 1: last_name
        ln = user_data.get('last_name', '').lower()
        if ln:
            components.append(ln)

        # 2: account/email local part
        account = user_data.get('email_local', '')
        if account:
            components.append(account)

        # 3: birth_year_short
        birth_short = user_data.get('birth_year_short', '')
        if birth_short:
            components.append(birth_short)

        # 4: phone_last4
        phone4 = user_data.get('phone_last4', '')
        if phone4:
            components.append(phone4)

        # 5: birth_mmddyy
        birth_mmddyy = user_data.get('birth_mmddyy', '')
        if birth_mmddyy:
            components.append(birth_mmddyy)

        # 应用TarGuess组合规则
        for combo in self.targess_rules['personal_info_combinations']:
            if len(combo) == 2:
                idx1, idx2 = combo
                if idx1 < len(components) and idx2 < len(components):
                    elem1 = components[idx1]
                    elem2 = components[idx2]

                    for sep in self.targess_rules['separators']:
                        base_guess = elem1 + sep + elem2

                        # 应用大小写变体
                        guesses.update(self.generate_capitalization_variants(base_guess))

                        # 应用leet变换
                        guesses.update(self.apply_leet_transform(base_guess, 0.4))

                        # 添加后缀
                        for suffix in self.targess_rules['suffix_patterns']:
                            guess_with_suffix = base_guess + suffix
                            guesses.add(guess_with_suffix)
                            guesses.update(self.generate_capitalization_variants(guess_with_suffix))

        return guesses

    def generate_context_sensitive_guesses(self, user_data):
        """基于用户上下文的智能猜测"""
        guesses = set()

        # 提取所有可用信息
        personal_info = []

        # 姓名相关
        fn = user_data.get('first_name', '').lower()
        ln = user_data.get('last_name', '').lower()
        initials = user_data.get('all_initials', '').lower()

        if fn: personal_info.append(fn)
        if ln: personal_info.append(ln)
        if initials: personal_info.append(initials)

        # 账号相关
        account = user_data.get('email_local', '')
        if account: personal_info.append(account)

        # 日期相关
        birth_elements = []
        if user_data.get('birth_year'):
            birth_elements.extend([
                user_data['birth_year'],
                user_data['birth_year_short'],
                user_data['birth_month'],
                user_data['birth_day'],
                user_data['birth_mmddyy'],
                user_data['birth_ddmmyy'],
                user_data['birth_yymmdd'],
                user_data['birth_md'],
                user_data['birth_dm']
            ])

        # 电话相关
        phone_elements = []
        if user_data.get('phone_last4'): phone_elements.append(user_data['phone_last4'])
        if user_data.get('phone_last6'): phone_elements.append(user_data['phone_last6'])

        all_elements = personal_info + birth_elements + phone_elements

        # 策略1: 个人信息优先组合
        if len(personal_info) >= 2:
            for i in range(min(3, len(personal_info))):
                for j in range(min(3, len(personal_info))):
                    if i != j:
                        elem1 = personal_info[i]
                        elem2 = personal_info[j]

                        # 各种组合方式
                        for sep in ['', '.', '_', '-']:
                            combo = elem1 + sep + elem2
                            if 4 <= len(combo) <= 16:
                                # 基础形式
                                guesses.update(self.generate_capitalization_variants(combo))

                                # 添加日期后缀
                                for date_elem in birth_elements[:5]:
                                    guesses.add(combo + date_elem)
                                    guesses.add(date_elem + combo)

                                # 添加电话后缀
                                for phone_elem in phone_elements:
                                    guesses.add(combo + phone_elem)
                                    guesses.add(phone_elem + combo)

        # 策略2: 姓名+数字模式
        if fn or ln:
            name_base = fn if fn else ln

            # 常见数字模式
            number_patterns = [
                '123', '1234', '12345', '123456',
                '111', '222', '333', '444', '555', '666', '777', '888', '999',
                '000', '007', '100', '200', '500', '1000',
                '01', '02', '03', '05', '08', '09',
                '1', '2', '3', '5', '7', '8', '9'
            ]

            for pattern in number_patterns[:15]:
                guesses.add(name_base + pattern)
                guesses.add(pattern + name_base)

                # 大小写变体
                guesses.update(self.generate_capitalization_variants(name_base + pattern))

        # 策略3: 键盘模式与个人信息结合
        for pattern in self.password_patterns['keyboard'][:5]:
            guesses.add(pattern)

            # 与个人信息组合
            for info in personal_info[:3]:
                if 3 <= len(info) <= 8:
                    guesses.add(info + pattern)
                    guesses.add(pattern + info)

                    # 添加分隔符版本
                    for sep in ['', '.', '_']:
                        guesses.add(info + sep + pattern)
                        guesses.add(pattern + sep + info)

        # 策略4: 特殊字符插入(不只是两端)
        base_guesses = list(guesses)[:30]
        for base in base_guesses:
            if 4 <= len(base) <= 10:
                # 在特定位置插入特殊字符
                insert_positions = [1, len(base) // 2, len(base) - 1]  # 开头、中间、结尾附近
                for pos in insert_positions:
                    if pos < len(base):
                        for char in self.special_chars[:8]:
                            new_guess = base[:pos] + char + base[pos:]
                            guesses.add(new_guess)

        return guesses

    def generate_advanced_leet_guesses(self, user_data):
        """应用高级leet变换策略"""
        guesses = set()

        # 基础个人信息
        fn = user_data.get('first_name', '').lower()
        ln = user_data.get('last_name', '').lower()
        account = user_data.get('email_local', '')

        personal_bases = []
        if fn: personal_bases.append(fn)
        if ln: personal_bases.append(ln)
        if account: personal_bases.append(account)

        # 对每个基础应用不同强度的leet变换
        for base in personal_bases:
            if 2 <= len(base) <= 12:
                # 低强度leet
                guesses.update(self.apply_leet_transform(base, 0.3))

                # 中强度leet
                guesses.update(self.apply_leet_transform(base, 0.6))

                # 高强度leet
                if len(base) <= 8:
                    strong_leet = self.apply_leet_transform(base, 0.8)
                    guesses.update(list(strong_leet)[:10])

                # leet变换后添加常见后缀
                leet_bases = list(self.apply_leet_transform(base, 0.5))
                for leet_base in leet_bases[:5]:
                    for suffix in ['123', '!', '1', '12', '1234']:
                        guesses.add(leet_base + suffix)

                    # 添加年份后缀
                    if user_data.get('birth_year_short'):
                        guesses.add(leet_base + user_data['birth_year_short'])

                    if user_data.get('birth_year'):
                        guesses.add(leet_base + user_data['birth_year'][2:])

        return guesses

    def generate_hybrid_guesses(self, user_data):
        """混合策略生成密码"""
        guesses = set()

        # 1. TarGuess-I策略
        targess_guesses = self.apply_targess_strategy(user_data)
        guesses.update(targess_guesses)

        # 2. 上下文敏感猜测
        context_guesses = self.generate_context_sensitive_guesses(user_data)
        guesses.update(context_guesses)

        # 3. 高级leet变换
        leet_guesses = self.generate_advanced_leet_guesses(user_data)
        guesses.update(leet_guesses)

        # 4. 常见密码模式
        guesses.update(self.common_passwords)

        return guesses

    def generate_for_user(self, user_data, max_guesses=20000):
        """为单个用户生成密码猜测 - 优化策略"""
        all_guesses = set()

        # 第1层:混合策略核心猜测
        hybrid_guesses = self.generate_hybrid_guesses(user_data)
        all_guesses.update(hybrid_guesses)

        # 第2层:扩展组合
        if len(all_guesses) < max_guesses * 0.7:
            # 生成更多变体
            base_guesses = list(hybrid_guesses)[:100]

            for base in base_guesses:
                if len(base) <= 12:
                    # 数字扩展
                    for i in range(0, 100, 10):
                        all_guesses.add(base + str(i).zfill(2))

                    # 特殊字符扩展
                    for char in self.special_chars[:5]:
                        all_guesses.add(base + char)
                        all_guesses.add(char + base)

                    # 年份扩展
                    if user_data.get('birth_year'):
                        all_guesses.add(base + user_data['birth_year'])
                        all_guesses.add(base + user_data['birth_year_short'])

        # 第3层:填充剩余空间
        if len(all_guesses) < max_guesses:
            # 添加更多键盘模式和序列
            for pattern in self.password_patterns['keyboard']:
                if len(all_guesses) < max_guesses:
                    all_guesses.add(pattern)

            for seq in self.password_patterns['sequences'][:10]:
                if len(all_guesses) < max_guesses:
                    all_guesses.add(seq)

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

        # 去重和智能排序
        unique_guesses = list(OrderedDict.fromkeys(valid_guesses))

        # 优化排序策略
        def password_priority(pwd):
            score = 0

            # 长度优先级:中等长度优先(6-10字符)
            if 6 <= len(pwd) <= 10:
                score += 50
            elif len(pwd) < 6:
                score += 30
            else:
                score += 10

            # 纯数字优先级较高
            if pwd.isdigit():
                score += 40

            # 字母数字组合优先级
            if pwd.isalnum() and not pwd.isdigit() and not pwd.isalpha():
                score += 30

            # 包含个人信息的优先级
            fn = user_data.get('first_name', '').lower()
            ln = user_data.get('last_name', '').lower()
            account = user_data.get('email_local', '').lower()

            if fn and fn in pwd.lower():
                score += 25
            if ln and ln in pwd.lower():
                score += 25
            if account and account in pwd.lower():
                score += 20

            # 生日信息优先级
            if user_data.get('birth_year_short') and user_data['birth_year_short'] in pwd:
                score += 15
            if user_data.get('phone_last4') and user_data['phone_last4'] in pwd:
                score += 15

            # 简单模式优先级高于复杂模式
            if sum(1 for c in pwd if c in self.special_chars) <= 1:
                score += 10

            return score

        unique_guesses.sort(key=password_priority, reverse=True)

        return unique_guesses[:max_guesses]

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

        for user in users:
            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

        print("数据统计分析:")
        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}%)")

        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 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)} 个用户...")

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

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

        return results

    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')

            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))

        avg_guesses = total_guesses // len(results) if results else 0

        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}")


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()
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值