第三章 编程习题3.2.4 实现仿射密码

3.24 编写一个加密解密程序实现习题 3.1 里的仿射密码。 

 

1. 信息:

这段代码实现了仿射密码(Affine Cipher)的加密和解密。仿射密码是一种使用数学函数进行加密和解密的方法,它依赖于两个关键的参数:a(乘数)和b(加数)。这里的代码包括了辅助函数来计算最大公约数(GCD)和模逆,以及主要的加密和解密函数。

2. 分析:

  • gcd函数:使用欧几里得算法计算两个数的最大公约数,确保a和字母表大小(这里是26,代表英文字母数量)互质。
  • modInverse函数:使用扩展的欧几里得算法找到模逆,这对于解密过程中计算逆元是必要的。
  • affineEncrypt函数:实现仿射密码的加密过程。检查a和26是否互质,然后对文本中的每个字母应用加密公式。
  • affineDecrypt函数:实现解密过程,利用模逆来逆转加密过程。
  • main函数:接收用户输入的文本和密钥(ab),展示加密和解密的结果。

3. 算法设计:

  • 采用仿射密码算法,加密公式为 E(x) = (ax + b) mod 26,解密公式为 D(x) = a_inv * (x - b) mod 26,其中 a_inva模26的乘法逆元。
  • 确保a和26互质以使加密函数可逆。
  • 使用模逆而不是试错法来找到乘法逆元,提高效率。

4. 代码实现(C++):

#include <iostream>
#include <string>

// 辅助函数:计算a和m的最大公约数(GCD)
int gcd(int a, int m) {
    while (m != 0) {
        int t = m;
        m = a % m;
        a = t;
    }
    return a;
}

// 辅助函数:使用扩展欧几里得算法找到a模m的逆
int modInverse(int a, int m) {
    for (int x = 1; x < m; x++) {
        if ((a * x) % m == 1)
            return x;
    }
    return 1; // 如果不存在逆元,返回1(理论上不应该发生,因为a和m应该是互质的)
}

// 加密函数
std::string affineEncrypt(std::string text, int a, int b) {
    std::string result = "";
    // 检查a和26是否互质
    if (gcd(a, 26) != 1) {
        std::cerr << "错误: a和字母表大小不互质,加密不可能进行。" << std::endl;
        return result;
    }
    for (char& c : text) {
        if (isalpha(c)) {
            char base = isupper(c) ? 'A' : 'a';
            result += char((a * (c - base) + b) % 26 + base);
        }
        else {
            result += c;
        }
    }
    return result;
}

// 解密函数
std::string affineDecrypt(std::string text, int a, int b) {
    std::string result = "";
    int a_inv = modInverse(a, 26);
    for (char& c : text) {
        if (isalpha(c)) {
            char base = isupper(c) ? 'A' : 'a';
            result += char(a_inv * ((c - base) - b + 26) % 26 + base);
        }
        else {
            result += c;
        }
    }
    return result;
}

// 主函数
int main() {
    std::string text;
    int a, b;

    std::cout << "请输入文本: ";
    getline(std::cin, text);
    std::cout << "请输入a的值(必须和字母表大小互质): ";
    std::cin >> a;
    std::cout << "请输入b的值: ";
    std::cin >> b;

    std::string encrypted = affineEncrypt(text, a, b);
    std::string decrypted = affineDecrypt(encrypted, a, b);

    std::cout << "加密文本: " << encrypted << std::endl;
    std::cout << "解密文本: " << decrypted << std::endl;

    return 0;
}

运行效果:

5. 实现代码过程中可能遇到的问题:

  • 如果a和26不互质,加密过程将无法进行,因为这意味着加密函数不可逆。
  • modInverse函数中,如果不存在模逆(理论上不应该发生如果a和26互质),函数返回1。这可能导致解密不正确。
  • 对于非字母字符,代码直接将其添加到结果中,不进行加密或解密。这可能不是某些情况下想要的行为。
  • 用户输入的错误处理(如非数字输入作为ab)可能导致程序异常结束。

6.总结

  1. 仿射密码理论

    • 了解到仿射密码是一种基于数学的简单替换加密技术,涉及到模算术和逆元的概念。
    • 认识到在实际应用中,选择正确的密钥(在本例中为ab)是确保加密有效和可解的关键。
  2. 模算术应用

    • 学习如何在编程中应用模算术,特别是在加密和解密的上下文中。
    • 了解如何计算最大公约数(GCD)来检查两个数是否互质,这对于确定加密函数是否可逆非常重要。
  3. 扩展欧几里得算法

    • 掌握如何实现扩展欧几里得算法来计算乘法逆元,这在许多加密算法中都是一个重要组成部分。
  4. C++编程实践

    • 通过具体实例学习C++的基本语法和结构,包括函数定义、循环、条件判断、I/O操作等。
    • 理解如何组织代码,使其模块化和易于阅读,通过定义清晰的函数来处理特定任务。
  5. 错误处理和边界条件

    • 识别和处理潜在的错误情况,例如非互质的密钥输入,以及理解在实际应用中进行健壮性检查的重要性。
    • 学习如何为特定情况(如非字母字符)设定边界条件。
  6. 安全意识

    • 虽然仿射密码在现代标准下不安全,但通过学习它,我们可以理解更复杂和安全的加密方法的基本原理。
    • 认识到在设计安全系统时考虑密钥空间大小、潜在的攻击方法(如暴力破解)的重要性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

夏驰和徐策

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

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

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

打赏作者

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

抵扣说明:

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

余额充值