Vigenere密码

  Vigenere密码

        Time Limit: 1 Sec  Memory Limit: 16M

 

Description

 

Vigenere密码是基于关键词的加密系统。关键词写在明文的下面(或上面),并不断重复书写,形成密钥流;使得每个明文字母都与一个关键字的字母关联。

例如:明文:this  is the plaintext ,关键词:hold。

 

加密过程为相应位置字母的和(mod 26)。

 

Input

输入包含T组测试数据,T<100。

对于每组测试数据,第1行包含一个正整数N (1<=N<=100000),接下来的一行是长度为N的明文字符串,第3行包含一个正整数M(1<M<N),下一行是长度为M的KEY字符串。所给字符串仅包含大写字母。

 

Output

输出每组测试数据的密文(仅包含大写字母),格式如sample out所示。

Sample Input

1

18

THISISTHEPLAINTEXT

4

HOLD

 

Sample Output

CASE#1:  AVTVPGEKLDWDPBEHEH

                                                                      题目来源:中南大学2012年11月新手赛

 

AC代码

 

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int main()
{
int t,n,m;
char s;
char ch[110000],ca[100000];
memset(ch,0,sizeof(ch));
scanf("%d",&t);
for (int i=1;i<=t;i++)
{
cin>>n;
getchar();
gets(ch);
cin>>m;
getchar();
gets(ca);
for (int p=0;ch[p];p++)
{
ch[p]=(ch[p]+ca[p%m]-'A'-'A')%26+'A';
}
printf("CASE#1:");
for (int q=0;ch[q];q++) {printf("%c",ch[q]);}
}
return 0;
}

之所以添加了这么多库,输入输出用的语言类型不一样,只是为了测试一下输入,C语言在输入字符串的时候存在一个很大的问题,。。。因为输入数据为一个整数,接着为一个字符串,再输入一个整数,再输入一个字符串。。,根据我的几次测试,如果用C语言,scanf分别读取的话,就会出现读入错误(测试数据的时候会发现),原因在于读入字符串时,会将之前输入的整数给“吃掉”,将整数也读入字符串中,这种情况的解决方法是在读入整数和字符串中间插入一句getchar()。。。。用C++中的cin.getline和gets读取时同样会发生这样的问题,解决的方法同上。

同时还有另外一种读入方法,是比较方便的。。即scanf("%d%s%d%s",&n,ch,&m,ca);用这个语句将四个变量一起输入,不会发现相互吃掉的对象。

这个题目对于做字符型的题目很有典型性,从上面的代码可以看出,字符型数据其实可以进行很方便的运算,加密算法要求对字符求和再mod26得到对应的字符,其实就是ASCII码的运算,但没有必要繁琐的将字符转化为整数进行运算再转化回来,直接可以用 ch[p]=(ch[p]+ca[p%m]-'A'-'A')%26+'A';这样的语句来得到相同的效果。

 

posted @ 2012-11-26 21:48  KRisen  阅读(1509)  评论(0编辑  收藏  举报