总时间限制: 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 }