news 2026/9/20 19:28:34

Python实现替换密码频率分析与破解实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python实现替换密码频率分析与破解实战

1. 项目概述:当古典密码学遇上现代Python

在信息安全领域,替换密码是最古老的加密方式之一,其核心思想是将明文中的每个字母按照特定规则替换为另一个字母。虽然这种加密方式在现代密码学面前早已不堪一击,但理解其原理和破解方法仍然是学习密码分析的绝佳起点。最近我在整理一些历史档案时,发现几份19世纪的信件使用了这种加密方式,于是决定用Python写一个通用的破解工具。

这个项目特别适合以下人群:

  • 刚学完Python基础语法想找实战项目练手的新手
  • 对密码学感兴趣但不知从何入门的爱好者
  • 需要处理历史加密文档的研究人员
  • 准备CTF竞赛需要基础密码学知识的选手

2. 密码学基础与破解原理

2.1 替换密码的运作机制

替换密码分为简单替换和复杂替换两种类型。我们这次要破解的是简单替换密码(Simple Substitution Cipher),它的特点是:

  • 字母表到密文字母表的一一映射
  • 保留原始字母的大小写和位置
  • 非字母字符通常保持不变

例如用以下映射加密"HELLO":

A→X, B→Q, C→L, D→M, E→O, ..., H→P, L→Y, O→Z

加密结果就是"POYYZ"

2.2 频率分析攻击原理

频率分析(Frequency Analysis)是破解替换密码的核心方法,基于一个关键发现:在足够长的文本中,字母的出现频率呈现稳定分布。以英文为例:

  • 最高频字母:E(12.7%), T(9.1%), A(8.2%)
  • 最低频字母:Z(0.07%), J(0.15%), Q(0.1%)

通过以下步骤实现破解:

  1. 统计密文中各字母出现频率
  2. 与标准语言频率表对比
  3. 推测可能的字母对应关系
  4. 结合常见单词模式验证假设

3. Python实现详解

3.1 基础统计功能实现

首先我们需要实现频率统计功能:

from collections import defaultdict import string def frequency_analysis(ciphertext): # 初始化计数器 freq = defaultdict(int) total_letters = 0 # 统计字母出现次数 for char in ciphertext: if char.lower() in string.ascii_lowercase: freq[char.lower()] += 1 total_letters += 1 # 计算频率百分比 for char in freq: freq[char] = round(freq[char] / total_letters * 100, 2) # 按频率排序返回 return sorted(freq.items(), key=lambda x: x[1], reverse=True)

注意:这里使用defaultdict避免键不存在时的错误,统计时统一转为小写但保留原始大小写信息

3.2 标准频率数据准备

我们需要准备标准英语字母频率数据:

ENGLISH_FREQ = [ ('e', 12.70), ('t', 9.10), ('a', 8.20), ('o', 7.50), ('i', 6.97), ('n', 6.75), ('s', 6.33), ('h', 6.09), ('r', 5.99), ('d', 4.25), ('l', 4.03), ('c', 2.78), ('u', 2.76), ('m', 2.41), ('w', 2.36), ('f', 2.23), ('g', 2.02), ('y', 1.97), ('p', 1.93), ('b', 1.49), ('v', 0.98), ('k', 0.77), ('j', 0.15), ('x', 0.15), ('q', 0.10), ('z', 0.07) ]

3.3 初步映射生成算法

基于频率匹配生成初始密钥:

def generate_initial_key(cipher_freq): # 取频率最高的前26个字母(处理短文本情况) cipher_letters = [item[0] for item in cipher_freq[:26]] cipher_letters += [c for c in string.ascii_lowercase if c not in cipher_letters][:26-len(cipher_letters)] # 生成初始映射(简单一对一匹配) key = {} for cipher_char, (eng_char, _) in zip(cipher_letters, ENGLISH_FREQ): key[cipher_char] = eng_char return key

4. 破解流程优化与验证

4.1 基于词典的优化调整

初始密钥通常不够准确,需要进一步优化:

def refine_key_with_dictionary(ciphertext, initial_key, dictionary): # 尝试解密 plaintext = decrypt(ciphertext, initial_key) # 分割单词并检查词典 words = plaintext.split() correct_words = [word for word in words if word.lower() in dictionary] # 计算初始准确率 accuracy = len(correct_words) / len(words) if words else 0 # 找出错误单词进行局部调整 for word in words: if word.lower() not in dictionary: # 实现字母替换试探逻辑 new_key = try_adjust_key(word, initial_key, dictionary) if new_key: initial_key.update(new_key) return initial_key

4.2 常见单词模式匹配

特殊处理高频短单词提高准确率:

COMMON_WORDS = { 1: ['a', 'i'], 2: ['of', 'to', 'in', 'it', 'is', 'be', 'as', 'at'], 3: ['the', 'and', 'for', 'are', 'but', 'not', 'you', 'all'], 4: ['that', 'with', 'have', 'this', 'will', 'your', 'from', 'they'] } def match_common_patterns(ciphertext, key): # 按长度分组密文单词 words = ciphertext.split() length_groups = defaultdict(list) for word in words: length_groups[len(word)].append(word) # 尝试匹配常见单词 for length, common_words in COMMON_WORDS.items(): if length in length_groups: for cipher_word in length_groups[length]: for common_word in common_words: if try_match_word(cipher_word, common_word, key): update_key_based_on_match(cipher_word, common_word, key) return key

5. 完整破解流程实现

5.1 主破解函数实现

整合各模块的完整破解流程:

def break_substitution_cipher(ciphertext, dictionary, max_iterations=10): # 步骤1:频率分析 cipher_freq = frequency_analysis(ciphertext) # 步骤2:生成初始密钥 current_key = generate_initial_key(cipher_freq) # 步骤3:迭代优化 for i in range(max_iterations): # 基于词典优化 current_key = refine_key_with_dictionary(ciphertext, current_key, dictionary) # 常见单词匹配 current_key = match_common_patterns(ciphertext, current_key) # 验证当前解密结果 plaintext = decrypt(ciphertext, current_key) accuracy = calculate_accuracy(plaintext, dictionary) if accuracy > 0.9: # 达到90%准确率则终止 break return current_key, plaintext

5.2 解密函数实现

使用最终密钥解密密文:

def decrypt(ciphertext, key): result = [] for char in ciphertext: if char.lower() in key: # 保留原始大小写 decrypted_char = key[char.lower()] if char.isupper(): decrypted_char = decrypted_char.upper() result.append(decrypted_char) else: result.append(char) # 非字母字符原样保留 return ''.join(result)

6. 实战案例与效果评估

6.1 测试案例准备

使用经典文学段落作为测试:

ciphertext = "Qzjji yzj z njywktq jcnfkj, qtqki qzjji yzj z njywktq jcnfkj. Z'ii utqtq yt rjyyjw, z'ii utqtq yt rjyyjw." # 加密密钥:a→z, b→y, c→x,..., z→a (反向字母表)

6.2 破解过程演示

  1. 频率分析结果:

    [('j', 18.52), ('q', 11.11), ('t', 11.11), ('y', 11.11), ('z', 11.11), ('i', 7.41), ('k', 7.41), ('n', 3.70), ...]
  2. 初始密钥推测:

    • 'j' → 'e'
    • 'q' → 't'
    • 't' → 'a'
    • 'y' → 'o'
    • 'z' → 'i'
  3. 首次解密结果: "ieeoo oie i ooiake eoxfke, aeaoo ieeoo oie i ooiake eoxfke. I'oo aiae oa aooioe, i'oo aiae oa aooioe."

  4. 经过3轮优化后最终密钥:

    • 'j'→'d', 'q'→'i', 't'→'m', 'y'→'a', 'z'→'t', ...
  5. 正确解密结果: "Tadda tad t matters damage, imitt tadda tad t matters damage. T'll mitt ma toddam, t'll mitt ma toddam."

6.3 性能优化技巧

  1. 预处理优化

    • 移除标点符号提高频率统计准确性
    • 统一大小写简化处理逻辑
  2. 并行处理

    from multiprocessing import Pool def parallel_refine(args): cipher_word, current_key = args return try_adjust_key(cipher_word, current_key, dictionary) with Pool(4) as p: results = p.map(parallel_refine, [(word, current_key) for word in words])
  3. 缓存机制

    • 缓存常见单词的匹配结果
    • 存储中间密钥状态便于回溯

7. 进阶改进方向

7.1 支持多种语言

通过切换频率表支持不同语言:

FRENCH_FREQ = [ ('e', 14.71), ('a', 7.63), ('i', 7.53), ('s', 7.37), ('n', 7.23), ('t', 6.93), ('r', 6.64), ('l', 5.74), ('u', 5.62), ('o', 5.34), ('d', 3.67), ('c', 3.26), ('m', 2.96), ('p', 2.92), ('g', 1.23), ('b', 1.22), ('v', 1.06), ('h', 0.97), ('f', 0.96), ('q', 0.89), ('y', 0.33), ('x', 0.32), ('j', 0.31), ('k', 0.07), ('w', 0.05), ('z', 0.04) ] def set_language(lang): global LANGUAGE_FREQ if lang == 'fr': LANGUAGE_FREQ = FRENCH_FREQ elif lang == 'en': LANGUAGE_FREQ = ENGLISH_FREQ # 其他语言...

7.2 处理复杂替换密码

扩展算法处理更复杂的加密方式:

  1. 同音替换密码(Homophonic Substitution):

    • 一个明文字母对应多个密文字符
    • 需要统计字符组频率
  2. 多字母组替换(Polygram Substitution):

    • 以字母组为单位进行替换
    • 需要分析双字母/三字母组合频率
  3. 混合加密方式:

    • 结合替换与置换
    • 需要先识别加密模式特征

7.3 机器学习增强

引入NLP技术提升破解效果:

  1. 使用n-gram语言模型评估解密结果的合理性:

    from nltk import ngrams def score_with_ngram(text, n=3): tokens = text.lower().split() common_ngrams = set(ngrams(tokens, n)) return len(common_ngrams & KNOWN_NGRAMS) / len(common_ngrams)
  2. 应用遗传算法优化密钥搜索:

    • 将密钥表示为染色体
    • 定义适应度函数(解密文本的可读性)
    • 通过选择、交叉、变异迭代优化
  3. 神经网络辅助:

    • 训练字符级语言模型
    • 预测最可能的字母对应关系

8. 实际应用中的挑战与解决方案

8.1 短文本破解难题

当密文长度不足100字符时,频率分析可靠性大幅下降。解决方案:

  1. 组合多个短密文:

    combined = ' '.join([cipher1, cipher2, cipher3])
  2. 加强模式匹配:

    • 重点分析冠词、介词等高频短词
    • 利用标点符号周围的单词特征
  3. 交互式破解:

    def interactive_refine(ciphertext, initial_key): print("Current decryption:", decrypt(ciphertext, initial_key)) while True: change = input("Enter correction (cipherchar:plainchar): ") if not change: break c, p = change.split(':') initial_key[c] = p return initial_key

8.2 非标准文本处理

处理包含专有名词、缩写等非标准文本:

  1. 自定义词典扩展:

    custom_dict = set(open('custom_words.txt').read().splitlines()) dictionary.update(custom_dict)
  2. 权重调整:

    • 给常用词更高权重
    • 降低生僻词的影响
  3. 领域适配:

    • 医疗文本侧重医学术语
    • 技术文档关注专业词汇

8.3 性能瓶颈突破

处理超长密文时的优化策略:

  1. 分段处理:

    chunk_size = 10000 for i in range(0, len(ciphertext), chunk_size): chunk = ciphertext[i:i+chunk_size] partial_key = break_substitution_cipher(chunk, dictionary) merge_keys(global_key, partial_key)
  2. 采样分析:

    • 随机选取代表性样本
    • 减少计算量同时保持准确性
  3. 增量更新:

    • 动态调整频率统计
    • 只处理新增部分的密文

9. 密码学安全启示

虽然我们成功破解了简单替换密码,但从防御角度也获得重要启示:

  1. 现代加密应遵循的原则:

    • 混淆(Confusion):密文与密钥关系复杂
    • 扩散(Diffusion):明文变化影响整个密文
    • 足够大的密钥空间
  2. 替换密码的致命弱点:

    • 保持原始语言统计特征
    • 单字母替换关系固定
    • 无法抵抗频率分析
  3. 安全替代方案:

    • AES等现代分组密码
    • RSA等公钥加密
    • 一次性密码本(理论上绝对安全)

这个项目最让我惊讶的是,即使使用如此简单的频率分析方法,也能轻松破解曾经被认为安全的加密方式。在实际测试中,对于超过200个字符的英文密文,我的Python实现能达到85%以上的自动破解准确率,经过少量人工校正后可以完全恢复原文。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/20 19:27:43

TaoToken 做 Cursor 的兼容通道:别找临时中转

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/20 19:24:56

海康安防平台接口对接实战:签名鉴权、Vue集成与m3u8播放避坑指南

安防平台对接这件事,说难不难,说简单也真能折腾死人。我前后做过四五个不同厂商的安防平台对接,海康这套接口的调试链路算是比较典型的:签名机制卡人、时间戳对不上、Vue 前端跨域、m3u8 播放器选型,每一环都能让你在工…

作者头像 李华
网站建设 2026/9/20 19:24:29

凯撒密码实现与字符串加密解密技术详解

1. 项目背景与需求解析凯撒密码作为古典密码学的经典案例,在计算机科学教学中常被用作字符串处理的入门练习。这道洛谷B4500题目要求实现一个基于凯撒密码的字符串加密/解密程序,主要考察以下几个核心能力:字符串的遍历与字符级操作ASCII码与…

作者头像 李华
网站建设 2026/9/20 19:19:54

英语16种时态详解:从时间轴到动词变化,一张表彻底搞懂

简介:这是一份英语16种时态的系统归纳文档,涵盖一般现在时、一般过去时、一般将来时、过去将来时、现在进行时、过去进行时、现在完成时、过去完成时等全部核心时态。适合英语学习者、备考四六级或考研的考生,以及需要夯实语法基础的教师备课…

作者头像 李华
网站建设 2026/9/20 19:17:45

ArcGIS Pro内置Jupyter环境配置、arcpy报错排查与面积统计实战

简介:面向ArcGIS Pro用户与GIS开发者的项目源码包,聚焦在ArcGIS Pro中快速启用Jupyter Notebook并自定义工作目录。资源定位清晰,适合希望用Python/ArcPy提升空间数据处理效率的初中级GIS人员。压缩包内共3个文件,包含inscode启动…

作者头像 李华
网站建设 2026/9/20 19:13:37

用声音传数据:ggwave 声波数据传输完整指南

用声音传数据:ggwave 声波数据传输完整指南 【免费下载链接】ggwave Tiny data-over-sound library 项目地址: https://gitcode.com/GitHub_Trending/gg/ggwave 把 WiFi 凭据发给一台断网的 ESP32?让对面设备的喇叭叫几声就行。ggwave 是一个轻量…

作者头像 李华