1402:Vigenère密码
时间限制: 1000 ms 内存限制: 65536 KB
提交数: 17245 通过数: 9250
【题目描述】
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;(前面相加大于z时,减z再减1,不减a了)
原文=密文-密钥+a;(前面相减小于0时,加上z再加上1,不加a)
#include<iostream> #include<cmath> #include<cstring> char a[105],b[1505]; using namespace std; int main() { int i=0,j,n,k=0,m=0,t=0; scanf("%s",a); scanf("%s",b); m=strlen(a);//取长度,然后转换为小写字符 for(i=0;i<m;i++) { if(a[i]>='A'&&a[i]<='Z') a[i]=a[i]+'a'-'A'; } n=strlen(b);//取密码长度,然后换成明文 for(i=0;i<n;i++) { if(b[i]>='A'&&b[i]<='Z')//大写时,因为还要照大写输出 { if((b[i]+'a'-'A'-a[i%m])<0)//i%m是密钥循环使用,m是密钥长度 b[i]='z'-a[i%m]+b[i]+1;//看表中是,把列看作密钥的话,行是明文,行加列(都从0开始)加a,(超过z的减z,再减1)那样,密文-密钥就有可能是负值,就需要+z+1; else b[i]=b[i]-a[i%m]+'a';} else//小写时 { if(( b[i]-a[i%m])<0) b[i]='z'+b[i]-a[i%m]+1; else b[i]=b[i]+'a'-a[i%m]; } } printf("%s",b); return 0; }