凯撒密码和playfair密码 实验报告.docx
《凯撒密码和playfair密码 实验报告.docx》由会员分享,可在线阅读,更多相关《凯撒密码和playfair密码 实验报告.docx(16页珍藏版)》请在冰豆网上搜索。
凯撒密码和playfair密码实验报告
一.预习准备
1.实验目的
(1).熟记古典对称密码的概念和特点;
(2).理解若干种古典密码体制的原理;
(3).掌握维吉尼亚及Playfair密码体制的编程实现。
2.实验环境
Widows7操作系统、MicrosoftVisualStudio2010(选择自己熟悉的编程语言和环境)
3.实验内容和要求
(1)实验内容
1.实现维吉尼亚密码体制;
2.实现Playfair密码体制。
(2)实验要求
1.复习课本/课件相关内容。
2.程序中不能固定密钥词,即用户可自行输入密钥词,然后对输入的明文进行加密,或对输入的密文进行解密
二.编程思路(实验原理)
维吉尼亚密码原理:
引入了“密钥”的概念,即根据密钥来决定用哪一行的密表来进行替换,以此来对抗字频统计。
Playfair原理:
根据下列规则一次对明文的两个字母加密:
(1)、属于相同对中的重复的明文字母将用一个填充字母进行分隔,因此,词balloon将被加密为balxloon。
(2)、属于该矩阵相同行的明文字母将由其右边的字母替代,而行的最后一个字母由行的第一个字母代替。
例如,ar被加密为RM。
(3)、属于相同列的明文字母将由它下面的字母代替,而列的最后一个字母由列的第一个字母代替。
例如,mu被加密为CM。
(4)、否则,明文的其他字母将由与其同行,且与下一个同列的字母代替。
因此,hs成为BP,ea成为IM(或JM,这可根据加密者的意愿而定)。
三.实验总结
1.实验程序(详细设计)
维吉尼亚代码:
#include
#include
#include
#defineN80
intmain(void)
{
charmessage[N];
intn,i;
intlength;
printf("明文:
");
gets(message);
printf("密钥:
");
scanf("%d",&n);
printf("明文:
");
puts(message);
printf("\n");
length=strlen(message);
for(i=0;i{
if(message[i]>='A'&&message[i]<='Z')
{
message[i]=((message[i]-'A')+n)%26+'A';
}
elseif(message[i]>='a'&&message[i]<='z')
{
message[i]=((message[i]-'a')+n)%26+'a';
}
elsecontinue;
}
puts("密文:
");
puts(message);
printf("\n");
return0;
}
Playfair代码:
voidencrypt()
{
inti,k;
constintN=100;
charletters[26]="ABCDEFGHIKLMNOPQRSTUVWXYZ";//用于填充矩阵
intflag[25]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};//字母是否已在矩阵中,与letters数组对应
charch[5][5];//5X5矩阵
charch1[N];//密钥
charch2[N];//明文
charch4;//无关字符
intlen='a'-'A';
cout<<"输入密钥:
";
cin>>ch1;
intflg=1;
while(flg==1)
{
for(inti=0;i{
if(ch1[i]>'z'||ch1[i]<'a')
{
cout<<"请重新选择操作:
"<flg=0;break;
}
else
ch1[i]=ch1[i]-len;
}
if(flg==1)
{for(i=0;iif(ch1[i]=='J')ch1[i]='I';
}
i=0;intj=0;
for(intk=0;k{
for(intt=0;t<25;t++)
{
if(ch1[k]==letters[t]&&flag[t]==0)
{
ch[i][j]=letters[t];
flag[t]=1;
if(j<4)j++;
else{i++;j=0;}
}
}
}
for(k=0;k<25;k++)
{
if(flag[k]==0)
{
ch[i][j]=letters[k];
flag[k]=1;
if(j<4)j++;
else{i++;j=0;}
}
}
cout<<"密钥填充后的矩阵为:
"<for(i=0;i<5;i++)
for(j=0;j<5;j++)
{
cout<cout<<"";
if(j==4)
cout<}
cout<cout<<"请输入明文(请输入英文字符):
";
cin>>ch2;
cout<<"输入一个无关字符:
";
cin>>ch4;
if(ch4>='a')
ch4=ch4-len;
for(k=0;k{
if(ch2[k]>='a')
ch2[k]=ch2[k]-len;
}
for(k=0;k{
if(ch2[k]=='J')
ch2[k]='I';
}
//为明文添加必要的无关字符以防止同一组的两个字符相同
for(k=0;k{
if(ch2[k]==ch2[k+1])
{
for(intt=strlen(ch2);t>k;t--)
ch2[t+1]=ch2[t];
ch2[k+1]=ch4;
}
}
//若明文有奇数个字符,则添加一个无关字符以凑够偶数个
if(strlen(ch2)%2!
=0)
{
ch2[strlen(ch2)+1]=ch2[strlen(ch2)];//字符串结尾赋'\0'
ch2[strlen(ch2)]=ch4;//明文串尾插入无关字符
}
cout<<"经过处理后的明文为:
";
for(k=0;kcout<cout<cout<<"其最终长度为:
"<//////////////////明文输入并整理完毕///////////////////////////////
for(k=0;k{
intm1,m2,n1,n2;
for(m1=0;m1<=4;m1++)
{for(n1=0;n1<=4;n1++)
{
if(ch2[k]==ch[m1][n1])break;
}
if(ch2[k]==ch[m1][n1])break;
}
for(m2=0;m2<=4;m2++)
{
for(n2=0;n2<=4;n2++)
{
if(ch2[k+1]==ch[m2][n2])break;
}
if(ch2[k+1]==ch[m2][n2])break;
}
m1=m1%5;
m2=m2%5;
if(n1>4){n1=n1%5;m1=m1+1;}
if(n2>4){n2=n2%5;m2=m2+1;}
if(m1==m2)
{
ch2[k]=ch[m1][(n1+1)%5];
ch2[k+1]=ch[m2][(n2+1)%5];
}
else
{
if(n1==n2)
{
ch2[k]=ch[(m1+1)%5][n1];
ch2[k+1]=ch[(m2+1)%5][n2];
}
else
{ch2[k]=ch[m1][n2];
ch2[k+1]=ch[m2][n1];
}
}
}
cout<<"加密后所得到的密文是:
";
for(k=0;kcout<cout<}elsebreak;
}
}
//解密算法
voiddecrypt()
{
inti,k;
constintN=100;
charletters[26]="ABCDEFGHIKLMNOPQRSTUVWXYZ";//用于填充矩阵
intflag[25]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
//标记字母是否已在矩阵中,与letters数组对应
charch[5][5];//5X5矩阵
charch1[N];//密钥
charch2[N];//密文
intlen='a'-'A';
intflg=1;
cout<<"输入密钥:
";
cin>>ch1;
while(flg==1)
{
for(inti=0;i{if(ch1[i]>'z'||ch1[i]<'a')
{
cout<<"请重新选择操作:
"<flg=0;break;
}
else
ch1[i]=ch1[i]-len;
}
if(flg==1)
{for(i=0;i{
if(ch1[i]=='J')ch1[i]='I';
}
i=0;intj=0;
//把密钥中的字母填入到矩阵中,并把该字母标记为已用
for(intk=0;k{
for(intt=0;t<25;t++)
{
if(ch1[k]==letters[t]&&flag[t]==0)
{
ch[i][j]=letters[t];
flag[t]=1;
if(j<4)j++;
else{i++;j=0;}
}
}
}
for(k=0;k<25;k++)//按字母表顺序把未用字母依次填入到矩阵中
{
if(flag[k]==0)
{
ch[i][j]=letters[k];
flag[k]=1;
if(j<4)j++;
else{i++;j=0;}
}
}
cout<<"密钥填充后的矩阵为:
"<for(i=0;i<5;i++)
for(j=0;j<5;j++)
{
cout<cout<<"";
if(j==4)
cout<}
cout</////////////////////矩阵生成完毕////////////////////////////
intf=0;
do{
cout<<"请输入密文(英文字符):
";
cin>>ch2;
for(intk=0;k{
if(ch2[k]>='a')
ch2[k]=ch2[k]-len;
}
for(k=0;k{
if(ch2[k]=='J')ch2[k]='I';
}
for(k=0;k{
if(ch2[k]==ch2[k+1])
{
cout<<"同一分组中不能出现相同字符!
请重新输入。
"<f=1;
break;
}elsef=2;
}
if(f==1)continue;
if(strlen(ch2)%2!
=0)
{
cout<<"字符串不能为奇数个!
请重新输入。
"<f=1;
}
elsef=2;
}while(f==1);
//解密开始
for(k=0;k{
intm1,m2,n1,n2;
for(m1=0;m1<=4;m1++)
{
for(n1=0;n1<=4;n1++)
{
if(ch2[k]==ch[m1][n1])break;
}
if(ch2[k]==ch[m1][n1])break;
}
for(m2=0;m2<=4;m2++)
{
for(n2=0;n2<=4;n2++)
{
if(ch2[k+1]==ch[m2][n2])break;
}
if(ch2[k+1]==ch[m2][n2])break;
}
m1=m1%5;
m2=m2%5;
if(n1>4){n1=n1%5;m1=m1+1;}
if(n2>4){n2=n2%5;m2=m2+1;}
if(m1==m2)
{ch2[k]=ch[m1][(n1+4)%5];
ch2[k+1]=ch[m2][(n2+4)%5];
}
else
{
if(n1==n2)
{
ch2[k]=ch[(m1+4)%5][n1];
ch2[k+1]=ch[(m2+4)%5][n2];
}
else
{
ch2[k]=ch[m1][n2];
ch2[k+1]=ch[m2][n1];
}
}
}
cout<<"解密后所得到的明文是:
";
for(k=0;kcout<cout<}
elsebreak;
}
}
2.实验结果
运行程序,通过调用函数执行一系列所需要的操作,程序运行正常,截图如下: