经典密码体制(上)

第4关:维吉尼亚密码

任务描述

在前面介绍的移位密码和代换密码中,一旦密钥被选定,则每个字母对应的数字都被加密变成对应的唯一数字。这种密码体制我们一般称为单表代换密码。下面介绍的是有名的维吉尼亚密码,这是一种多表代换密码。

本关任务:用 C++ 实现维吉尼亚密码,然后对输入的明文字符串进行维吉尼亚加密后打印输出。

相关知识

为了完成本关任务,你需要掌握:维吉尼亚密码的密码体制。

维吉尼亚密码的密码体制

维吉尼亚密码(又译维热纳尔密码)是使用一系列凯撒密码组成密码字母表的加密算法,属于多表密码的一种简单形式。下面给出具体定义。 设m是一个正整数,定义P=C=K=(Z26​)m(这里之所以会多出一个m次方,就是因为维吉尼亚密码是一个多表代换,即对于相同的明文可以对应不同的密文)。对任意的密钥K=(k1​,k2​,...,km​),定义: ek​(x1​,x2​,...,xm​)=(x1​+k1​,x2​+k2​,...,xm​+km​) 这个是加密函数。 dk​(y1​,y2​,...,ym​)=(y1​−k1​,y2​−k2​,...,ym​−km​) 这个是解密函数。 以上所有的运算都是在Z26​上进行。 相信你看到这里还是一知半解,下面我们通过一个例子来让你真正的学会维吉尼亚密码。 假设m=6,密钥字为“CIPHER”,其对应于如下的数字串K=(2,8,15,7,4,17)。要加密的明文为thiscryptos。 那么我们可以把明文转化为对应的数字,使用密钥字进行模26的运算。

1978182172415191418
28157417281574
211523256802382122

那么相应的密文为:vpxzgiaxivw。 从上面这个例子我们可以观察到,维吉尼亚密码体制实际上就是对密钥串的多次重复利用,最终得出每个明文字符的密文。 我们可以从这里看出,维吉尼亚密码的密钥空间大小为26m,所以即使m的值很小,使用穷尽密钥搜索方法也需要很长时间。比如当m=5的时候,密钥空间大小超过1.1×107,这样的范围超过了手算进行穷尽搜索的能力范围。 一般来说多表代换密码比单表代换密码更为安全一些。

编程要求

本关的编程任务是,补全右侧编辑器 Begin-End 区间的代码,实现给定字符串的加密功能,具体要求如下:

  • 给定密钥串以及明文串,打印输出密文串(密文串全部为小写字母)。

注意:遇到大写字母要变换成小写字母来处理。

测试说明

平台会对你编写的代码进行测试:

测试输入:

 
  1. ewdsa
  2. dsadsvccvcxv

预期输出:

 
  1. hodvszyfncbr

测试输入:

 
  1. dderc
  2. sacxvcxbfhjSDDAchdzcbnxz

预期输出:

 
  1. vdgoxfafwjmvhucfkhqeeqbq

代码:

#include<bits/stdc++.h>  
using namespace std;  
  
// 函数来加密单个字符  
char encryptChar(char plainChar, char keyChar) {  
    plainChar = tolower(plainChar); // 转换为小写  
    keyChar = tolower(keyChar);     // 转换为小写  
    char offset = keyChar - 'a';    // 计算偏移量  
    return (plainChar - 'a' + offset) % 26 + 'a'; // 应用偏移并转换回字符  
}  
  
// 函数来加密整个字符串  
string encryptString(string plainText, string key) {  
    string cipherText = "";  
    int keyIndex = 0;  
    for (char c : plainText) {  
        if (isalpha(c)) { // 只处理字母  
            cipherText += encryptChar(c, key[keyIndex]);  
            keyIndex = (keyIndex + 1) % key.length(); // 更新密钥索引  
        } else {  
            cipherText += c; // 非字母字符保持不变  
        }  
    }  
    return cipherText;  
}  
  
int main()  
{  
    string A, B;  
    cin >> A; // 读取密钥  
    cin >> B; // 读取明文  
      
    /*********** Begin ***********/  
    string encrypted = encryptString(B, A); // 对明文进行加密  
    cout << encrypted; // 打印密文  
    /*********** End ***********/  
  
    return 0;  
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值