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=mi®ki,运算®的规则如下表所示:
Vigenère 加密在操作时需要注意:
®运算忽略参与运算的字母的大小写,并保持字母在明文 M 中的大小写形式;
例如,明文 M=Helloworld,** k=abc 时,密文 C=Hfnlpyosnd。
输入共 2 行。
第一行为一个字符串,表示** k,长度不超过 100,其中仅包含大小写字母。第二行
为一个字符串,表示经加密后的密文,长度不超过 1000,其中仅包含大小写字母。
输出格式:输出共 1 行,一个字符串,表示输入**和密文所对应的明文。
【数据说明】
对于 100%的数据,输入的**的长度不超过 100,输入的密文的长度不超过 1000,且
都仅包含英文字母。
NOIP 2012 提高组 第一天 第一题
#include<iostream>#include<cstring>#include<string>#include<cstdio>using namespace std; //字母'A'的ASCII码是41H(0100 0001B),字母'a'的ASCII码是61H(0110 0001B),//字母'Z'的ASCII码是5AH(0101 1010B), 字母'z'的ASCII码是7AH(0111 1010B) //字母'A'与'a'的二进制后5位是相同的,所以无论是大写字母还是小写字母x//x &31(1 1111B)的值就是x在字母表里的顺序。//我这是方便定位//temp记录的是向后窜的位数 //通过找规律可知,ori向后窜位的大小是key字母在字母表的顺序-1 int main(){ int i,temp; string ori,key; cin>>key>>ori; for(i=0;i<ori.size();i++) { temp=(key[i%key.size()]&31)-1;// 括号 ori[i]=(ori[i]&31)-temp>0?ori[i]-temp:ori[i]-temp+26;//+26不就像不够借位吗?26进制。输入的是密文,所以减 } //明文变密文才是加 cout<<ori<<endl; //>0,A-1==0,往后挪自然要加26 return 0; }