A24183. Vigenère密码
填空题
较难
知识点
题目描述
Vigenère密码
题目描述
16世纪法国外交家Blaise de Vigenère设计了一种多表密码加密算法——Vigenère密码。Vigenère密码的加密解密算法简单易用,且破译难度比较高,曾在美国南北战争中为南军所广泛使用。
在密码学中,我们称需要加密的信息为明文,用M表示;称加密后的信息为密文,用C表示;而密钥是一种参数,是将明文转换为密文或将密文转换为明文的算法中输入的数据,记为k。 在Vigenère密码中,密钥k是一个字母串,k=k1k2…kn。当明文 M=m1m2…mn时,得到的密文 C=c1c2…cn,其中ci=m_i® k_i,运算® $的规则如下表所示:

Vigenère加密在操作时需要注意:
1.®运算忽略参与运算的字母的大小写,并保持字母在明文M中的大小写形式;
2.当明文M的长度大于密钥 k 的长度时,将密钥 k 重复使用。
例如,明文M=Helloworld,密钥k=abc时,密文C=Hfnlpyosnd。

输入
第一行为一个字符串,表示密钥 k,长度不超过100,其中仅包含大小写字母。
第二行为一个字符串,表示经加密后的密文,长度不超过1000,其中仅包含大小写字母。
输出
输出共1行,一个字符串,表示输入密钥和密文所对应的明文。
输入样例
CompleteVictory
Yvqgpxaimmklongnzfwpvxmniytm输出样例
Wherethereisawillthereisaway参考答案
#include<bits/stdc++.h>
using namespace std;
int num(char c)
{
return islower(c) ? c-'a' : c-'A';
}
int main()
{
string k, s;
cin >> k >> s;
for(int i = 0; i < s.length(); ++i)
s[i] = (isupper(s[i]) ? 'A' : 'a')+(num(s[i])-num(k[i%k.size()])+26)%26;
cout << s;
return 0;
}答案解析
#include<bits/stdc++.h>
using namespace std;
int main()
{
int keyNum[105] = {}, lenk;
string k, s;
cin >> k >> s;
lenk = k.length();
for(int i = 0; i < lenk; ++i)
keyNum[i] = toupper(k[i])-'A';//字母转为0~25的数值
for(int i = 0; i < s.length(); ++i)
{
if(islower(s[i]))
{
s[i] = s[i]-keyNum[i%lenk];
if(s[i] < 'a') s[i] += 26;
}
else
{
s[i] = s[i]-keyNum[i%lenk];
if(s[i] < 'A') s[i] += 26;
}
}
cout << s;
return 0;
}
上一题
下一题