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,运算®的规则如下表所示:

 08:Vigenère密码题解_第1张图片

Vigenère加密在操作时需要注意:

1. ®运算忽略参与运算的字母的大小写,并保持字母在明文M中的大小写形式;

2. 当明文M的长度大于密钥k的长度时,将密钥k重复使用。

明文

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

例如,明文M=Helloworld,密钥k=abc时,密文C=Hfnlpyosnd。

 

输入

输入共2行。 
第一行为一个字符串,表示密钥k,长度不超过100,其中仅包含大小写字母。第二行为一个字符串,表示经加密后的密文,长度不超过1000,其中仅包含大小写字母。

对于100%的数据,输入的密钥的长度不超过100,输入的密文的长度不超过1000,且都仅包含英文字母。

输出

输出共1行,一个字符串,表示输入密钥和密文所对应的明文。

样例输入

CompleteVictory

Yvqgpxaimmklongnzfwpvxmniytm

样例输出

Wherethereisawillthereisaway

来源

NOIP2012复赛 提高组 第一题

 

 

题解:

1.有题目可知此题应当使用函数来将密文、密匙转化为明文;

2.更具下图我们可以找到以下规律:

08:Vigenère密码题解_第2张图片

a) 每一行的开头都是本行的字母;

b) a-z循环出现;

3.所以,我们可以通过这个来编写转换函数,如下:

char zh(char mi,char key)

{

int j,n;

for(j=key;j<=key+26;j++)     //通过循环来判定所在的位置

{

if(j==mi||j-26==mi) //如下图我们可以将此表扩展就会出   现第二组循环(每组循环26个字   母)

{

n=j-(key-'a'); //如下图我们可知:明文=找到的字母   所在位-(这行的开头字母-‘a

return n;

}

}

}

 08:Vigenère密码题解_第3张图片

4.函数写完后再来考虑主函数;

5.主函数中,因为密文和密匙的长度不同,所以我们需要用两个变量(ih)来储存他们;

6.两个变量一个用于for循环,另一个写在循环内部;

7.我们需要用到strlen函数来计算密匙与密文的长度(头文件#include);

8.除此之外我们需要考虑大小写的问题,在循环中我们就可以将密文与密匙统一;

9.注意:密文的字母需要在执行完上述函数后应当恢复其函数的原本大小写但密匙不用;

10.注意:此题中的三个字符串建议开成全局变量。

程序:

#include

#include

char m[1000],k[100],c[1000];

char zh(char mi,char key)

{

int j,n;

for(j=key;j<=key+26;j++)

{

if(j==mi||j-26==mi)

{

n=j-(key-'a');

return n;

}

}

}

int main()

{

int l1,l2,e,h=0,i,n;

scanf("%s",k);

scanf("%s",c);

l1=strlen(k);

l2=strlen(c);

for(i=0;i

{

e=0;

if(k[h]>='A'&&k[h]<='Z')

k[h]=k[h]+('a'-'A');

if(c[i]>='A'&&c[i]<='Z')

{

c[i]=c[i]+('a'-'A');

e=1;

}

m[i]=zh(c[i],k[h]);

if(e==1)

m[i]=m[i]-('a'-'A');

printf("%c",m[i]);

h++;

if(h>=l1) h=0;

}


你可能感兴趣的:(08:Vigenère密码题解)