08:Vigenère密码
- 总时间限制:
- 1000ms
- 内存限制:
- 65536kB
- 描述
-
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加密在操作时需要注意:
1. ®运算忽略参与运算的字母的大小写,并保持字母在明文M中的大小写形式;
2. 当明文M的长度大于密钥k的长度时,将密钥k重复使用。
例如,明文M=Helloworld,密钥k=abc时,密文C=Hfnlpyosnd。
明文 H e l l o w o r l d 密钥 a b c a b c a b c a 密文 H f n l p y o s n d - 输入
- 输入共2行。
第一行为一个字符串,表示密钥k,长度不超过100,其中仅包含大小写字母。第二行为一个字符串,表示经加密后的密文,长度不超过1000,其中仅包含大小写字母。
对于100%的数据,输入的密钥的长度不超过100,输入的密文的长度不超过1000,且都仅包含英文字母。 - 输出
- 输出共1行,一个字符串,表示输入密钥和密文所对应的明文。
- 样例输入
-
CompleteVictory Yvqgpxaimmklongnzfwpvxmniytm
- 样例输出
-
Wherethereisawillthereisaway
- 来源
- NOIP2012复赛 提高组 第一题
-
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<cmath> 5 using namespace std; 6 char my[10001];//密钥 7 char miwen[1001];//密文 8 char mingwen[1001];//明文 9 char zd[101][101];//储存明文密文密钥的字典 10 int yn1[1001];//是否需要-32 11 int main() 12 { 13 scanf("%s",&my); 14 scanf("%s",&miwen); 15 int lmy=strlen(my);//密钥的长度 16 int lmiwen=strlen(miwen);//明文的长度 17 for(int i=1;i<=26;i++) 18 { 19 char bg=(char)(i+64); 20 for(int j=1;j<=26-i+1;j++) 21 { 22 zd[i][j]=bg; 23 bg++; 24 } 25 }//建立字典 26 for(int i=2;i<=26;i++) 27 { 28 char bg=64; 29 for(int j=26-i+1;j<=26;j++) 30 { 31 zd[i][j]=bg; 32 bg++; 33 } 34 } 35 for(int i=0;i<lmy;i++) 36 { 37 if(my[i]>=90&&my[i]<=122) 38 my[i]=my[i]-32; 39 }//将密钥全部转换为大写字母 40 for(int i=0;i<lmiwen;i++) 41 { 42 if(miwen[i]>=97&&miwen[i]<=122) 43 { 44 miwen[i]=miwen[i]-32; 45 yn1[i]=1; 46 } 47 }//将密文全部转换为大写字母 48 int cs=lmiwen/lmy+1; 49 while(cs!=1) 50 { 51 strncat(my,my,lmy); 52 cs--; 53 }//将密钥复制到足够长 54 /*for(int i=1;i<=26;i++) 55 { 56 for(int j=1;j<=26;j++) 57 { 58 cout<<zd[i][j]<<" "; 59 } 60 cout<<endl; 61 }//建立字典 */ 62 for(int i=0;i<lmiwen;i++) 63 { 64 int amy=(int)my[i];//密文对应密钥的ascll码表 65 int amw=(int)miwen[i];//第i个密文的ascll码表 66 if(amy<=amw) 67 { 68 if(yn1[i]==1) 69 { 70 cout<<(char)(amw-amy+65+32); 71 } 72 else cout<<(char)(amw-amy+65); 73 } 74 else 75 //cout<<(char)(amy-amw+73); 76 { 77 int now=0; 78 for(int j=1;j<=26;j++) 79 { 80 if(zd[26][j]==amw) 81 { 82 now=26+j; 83 break; 84 } 85 } 86 if(yn1[i]==1) 87 { 88 cout<<char((now-(amy-64))+64+32); 89 } 90 else cout<<char((now-(amy-64))+64); 91 } 92 } 93 return 0; 94 }