课后编程习题3.25 字母频率攻击Casear(凯撒)密码

3.25 写一个程序,无须人工干预,对加法密码实现字母频率攻击。软件按可能性大小的顺序给出可能的明文。如果用户界面允许用户定义 “给出前 10个可能明文”,则更好。

我的答案:

一、信息(题目的有用信息)

这段代码实现了一种简化版的英语字母频率分析方法,用于破解加密文本。主要组件包括:

  • 英文字母的标准频率表standardFrequencies
  • calculateFrequency函数,计算给定文本的字母频率。
  • decryptCaesarCipher函数,尝试解密给定的凯撒密码文本。
  • compareFrequencies函数,比较两个频率分布的差异。
  • 主函数main,接受用户输入的密文,尝试各种移位解密,并根据频率分析的结果排序。

二、分析(包括每个信息的作用和思考过程和分析过程)

  • 标准频率表:为比较提供基准,因为自然语言中字母出现的频率是有特定模式的。
  • calculateFrequency函数:理解密文或解密文本的特征,为找出正确的移位提供依据。
  • decryptCaesarCipher函数:核心解密机制,通过遍历所有可能的移位来找到可能的明文。
  • compareFrequencies函数:通过比较解密文本的频率与标准频率的差异,评估每个解密选项的可能性。
  • 主函数:用户交互的接口,收集密文,执行解密尝试,并展示可能的解密结果。

三、算法设计

  1. 输入密文:从用户那里获取需要解密的文本。
  2. 遍历所有可能的移位:从0到25,尝试每种可能的移位。
  3. 对每种移位解密并计算频率:使用decryptCaesarCipher解密文本,然后用calculateFrequency计算频率。
  4. 评估与标准频率的差异:用compareFrequencies比较当前解密文本的频率与标准频率的差异。
  5. 记录和排序结果:将每次尝试的解密文本及其差异记录下来,并根据差异排序。
  6. 输出最可能的解密文本:显示差异最小的前N个解密选项。

四、代码实现(用C++)

#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <algorithm>
#include <cmath>

// 英语字母频率(简化版)
const std::map<char, double> standardFrequencies = {
    {'A', 8.167}, {'B', 1.492}, {'C', 2.782}, {'D', 4.253}, {'E', 12.702},
    {'F', 2.228}, {'G', 2.015}, {'H', 6.094}, {'I', 6.966}, {'J', 0.153},
    {'K', 0.772}, {'L', 4.025}, {'M', 2.406}, {'N', 6.749}, {'O', 7.507},
    {'P', 1.929}, {'Q', 0.095}, {'R', 5.987}, {'S', 6.327}, {'T', 9.056},
    {'U', 2.758}, {'V', 0.978}, {'W', 2.360}, {'X', 0.150}, {'Y', 1.974},
    {'Z', 0.074}
};

// 计算一个字符串的字母频率
std::map<char, double> calculateFrequency(const std::string& text) {
    std::map<char, double> freq;
    for (char c : text) {
        if (isalpha(c)) {
            c = toupper(c);  // 将所有字母转换为大写
            freq[c]++;
        }
    }
    int total = text.size();
    for (auto& pair : freq) {
        pair.second = (pair.second / total) * 100;  // 转换为百分比
    }
    return freq;
}

// 解密加法密码给定特定的移位
std::string decryptCaesarCipher(const std::string& text, int shift) {
    std::string decrypted;
    for (char c : text) {
        if (isalpha(c)) {
            char base = isupper(c) ? 'A' : 'a';
            c = ((c - base - shift + 26) % 26) + base;
        }
        decrypted += c;
    }
    return decrypted;
}

// 比较两个频率分布,返回它们的差异
double compareFrequencies(const std::map<char, double>& freq1, const std::map<char, double>& freq2) {
    double diff = 0;
    for (auto& pair : freq1) {
        char letter = pair.first;
        double freq = pair.second;
        diff += std::abs(freq - freq2.at(letter));
    }
    return diff;
}

int main() {
    std::string ciphertext;
    std::cout << "请输入密文: ";
    getline(std::cin, ciphertext);

    std::vector<std::pair<std::string, double>> possiblePlaintexts;

    // 尝试每个可能的移位
    for (int shift = 0; shift < 26; ++shift) {
        std::string decrypted = decryptCaesarCipher(ciphertext, shift);
        std::map<char, double> decryptedFreq = calculateFrequency(decrypted);
        double diff = compareFrequencies(decryptedFreq, standardFrequencies);

        possiblePlaintexts.push_back(std::make_pair(decrypted, diff));
    }

    // 根据差异对候选明文进行排序
    sort(possiblePlaintexts.begin(), possiblePlaintexts.end(), [](const auto& a, const auto& b) {
        return a.second < b.second; // 按照差异排序
        });

    // 输出前N个结果
    int N;
    std::cout << "请输入你想查看的可能明文数量:";
    std::cin >> N;
    std::cout << "可能的明文:" << std::endl;
    for (int i = 0; i < N && i < possiblePlaintexts.size(); ++i) {
        std::cout << i + 1 << ": " << possiblePlaintexts[i].first << " (差异: " << possiblePlaintexts[i].second << ")" << std::endl;
    }

    return 0;
}

密文生成:(读者如果想先用凯撒密码加密可以看我这篇文章传送门:第三章编程习题 之 广义Caesar密码实现)

明文生成:

 

五、实现代码过程中可能遇到的问题

  • 性能问题:频繁的字符串操作和频率计算可能会导致效率问题,特别是对于较长的文本。
  • 大小写敏感性:代码当前假设所有英文字母都是大写的,如果输入小写字母可能无法正确计算频率。
  • 非字母字符处理:代码只处理字母并忽略其他字符,对于包含非字母字符的文本,频率计算可能不准确。
  • 固定的语言模型:标准频率表是基于一般英语文本的,可能不适合所有类型和风格的文本。

六、学到了什么?

  1. 编程基础

    • C++语言应用:了解和实践C++语言的基本语法和结构,包括向量、映射、字符串处理等。
    • 函数编写:学习如何将问题拆分成子问题,通过编写和调用函数解决每个子问题。
  2. 算法思维

    • 解决问题的步骤:通过分析问题,设计出一步步解决问题的算法。
    • 循环和条件:理解如何使用循环遍历所有可能性,并使用条件语句选择最佳解。
  3. 数据结构应用

    • 映射(Map):利用映射来存储和快速访问字母频率。
    • 向量(Vector):使用向量存储和处理多个可能的解。
  4. 密码学基础

    • 凯撒密码原理:了解凯撒密码的加密和解密原理,即字母表的简单替换。
    • 频率分析:认识到在某些语言中,字母出现的频率是有规律的,这个特性可以用来破解替换密码。
  5. 数学应用

    • 模运算:在进行字母替换时,理解和应用模运算来处理字母表的循环。
    • 频率计算:通过数学方式计算和比较字母频率。
  6. 问题解决技能

    • 调试和测试:在编写和运行代码的过程中,学会如何调试和测试以确保代码的正确性。
    • 性能考虑:了解代码效率对于解决问题的重要性,尤其是在处理大量数据时。
  7. 实际应用与批判性思维

    • 安全意识:理解简单密码的脆弱性,提高对信息安全和加密技术的认识。
    • 算法的局限性:意识到算法可能不适用于所有情况,例如语言或文本风格的变化可能影响破解效果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夏驰和徐策

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值