08:Vigenère密码

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 } 

 

posted @ 2017-03-09 07:41  自为风月马前卒  阅读(493)  评论(1编辑  收藏  举报

Contact with me