1402:Vigenère密碼
時間限制: 1000 ms 內存限制: 65536 KB
提交數: 6704 通過數: 3761
【題目描述】
6世紀法國外交家Blaise de Vigenère設計了一種多表密碼加密算法——Vigenère密碼。Vigenère密碼的加密解密算法簡單易用,且破譯難度比較高,曾在美國南北戰爭中爲南軍所廣泛使用。
在密碼學中,我們稱需要加密的信息爲明文,用M表示;稱加密後的信息爲密文,用C表示;而密鑰是一種參數,是將明文轉換爲密文或將密文轉換爲明文的算法中輸入的數據,記爲k。 在Vigenère密碼中,密鑰k是一個字母串,k=k1k2…kn。當明文M=m1m2…mn時,得到的密文C=c1c2…cn,其中ci=mi®ki,運算®的規則如下表所示:
Vigenère加密在操作時需要注意:
1.®運算忽略參與運算的字母的大小寫,並保持字母在明文M中的大小寫形式;
2.當明文M的長度大於密鑰k的長度時,將密鑰k重複使用。
例如,明文M=Helloworld,密鑰k=abc時,密文C=Hfnlpyosnd。
【輸入】
第一行爲一個字符串,表示密鑰k,長度不超過100,其中僅包含大小寫字母。
第二行爲一個字符串,表示經加密後的密文,長度不超過1000,其中僅包含大小寫字母。
對於100%的數據,輸入的密鑰的長度不超過100,輸入的密文的長度不超過1000,且都僅包含英文字母。
【輸出】
輸出共1行,一個字符串,表示輸入密鑰和密文所對應的明文。
【輸入樣例】
CompleteVictory
Yvqgpxaimmklongnzfwpvxmniytm
【輸出樣例】
Wherethereisawillthereisaway
思路:將密鑰轉換爲大寫字母,從頭開始解密,大寫的情況,按規則解密,若明文小於A,從字母表倒序轉換。小寫的情況,按規則解密,若明文小於a,從字母表倒序轉換,若明文長度大於密鑰長度,重複使用密鑰。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
void turn(char &x)
{
if((x >= 'a') && (x <= 'z'))
x -= 32;
}
int main()
{
char key[1000],s[1000];
int lena,lenb;
int i,j;
gets(key);//輸入密鑰
gets(s);//輸入密文
lena=strlen(key);//求密鑰長度
lenb=strlen(s);//求密文長度
for(i = 0; i < lena; i++) //將密鑰轉換爲大寫字母
turn(key[i]);
for(i=0,j = 0; i < lenb; i++) //從頭開始解密
{
if(s[i] <= 'Z')//大寫的情況
{
s[i] = s[i] - (key[j]-'A');//按規則解密
j++;
if(s[i] < 'A')//若明文小於A
s[i] = 'Z'-('A'-s[i])+1;//從字母表倒序轉換
}
else//小寫的情況
{
s[i] = s[i] - (key[j]-'A');//按規則解密
j++;
if(s[i] < 'a')//若明文小於a
s[i] = 'z' - ('a'-s[i]) + 1;//從字母表倒序轉換
}
if(j > lena - 1)//若明文長度大於密鑰長度,重複使用密鑰
j = 0;
}
cout << s << endl;
return 0;
}