实验1古典密码算法.docx
《实验1古典密码算法.docx》由会员分享,可在线阅读,更多相关《实验1古典密码算法.docx(20页珍藏版)》请在冰豆网上搜索。
实验1古典密码算法
实验1古典密码算法
一、实验目的
通过编程实现替代密码算法和置换密码算法,加深对古典密码体系的了解,为以后深入学习密码学奠定基础。
二、实验原理
古典密码算法曾被广泛应用,大都比较简单。
它的主要应用对象是文字信息,利用密码算法实现文字信息的加密和解密。
其中替代密码和置换密码是具有代表性的两种古典密码算法。
1、替代密码
替代密码算法的原理是使用替代法进行加密,就是将明文中的字符用其他字符替代后形成密文。
例如,明文字母a、b、c、d,用D、E、F、G做对应替换后形成密文。
最早的替代密码是由JuliusCaesar发明的Caesar(恺撒)密码,又叫循环移位密码。
它的加密过程可以表示为下面的函数:
E(m)=(m+k)modn
其中,m为明文字母在字母表中的位置数;n为字母表中的字母个数;k为密钥;E(m)为密文字母在字母表中对应的位置数。
例如,对于明文字母H,其在字母表中的位置数为8,设k=4,则按照上式计算出来的密文为L,计算过程如下:
E(8)=(m+k)modn=(8+4)mod26=12=L
解密算法是:
m=D(L)=(L-k)mod26
2、置换密码
置换密码算法的原理是不改变明文字符,只将字符在明文中的排列顺序改变,从而实现明文信息的加密。
置换密码又称为换位密码。
矩阵换位法是实现置换密码的一种常用方法。
它将明文中的字母按照给定的顺序安排在一个矩阵中,然后又根据密钥提供的顺序重新组合矩阵中的字母,从而形成密文。
例如,明文为attackbeginsatfive,密钥为cipher,将明文按照每行6个字母的形式排在矩阵中,形成如下形式:
attack
begins
atfive
根据密钥cipher中各字母在字母表中出现的先后顺序,得到给定的一个置换:
f=145326
因此有:
密钥:
145326
明文:
attack
begins
atfive
根据上面的置换,将原有矩阵中的字母按照第1列、第4列、第5列、第3列、第2列、第6列的顺序排列、则有下面的形式:
aacttk
binges
aivfte
从而得到密文:
abatgftetcnvaiikse
其解密过程是根据密钥的字母数作为列数,将密文按照列、行的顺序写出,再根据由密钥给出的矩阵置换产生新的矩阵,从而恢复明文。
3、算法设计
1、替代算法
采用循环移位的算法。
从键盘接收明文或密文str和密钥k,然后根据公式E(m)=(m+k)modn得到改变后的密文或明文,然后输出到屏幕。
2、置换算法
从键盘接收明文或密文str和密钥k,然后根据密钥的长度把str中的字符串存到二维数组temp1中,然后根据密钥对二维数组中的数据进行两次置换,将置换后的数组按列输出就得到了密文或明文。
4、函数接口
1、/*替代密码的加密函数*/
charsubstitute(charmessage[])//定义substitute函数
实现功能:
把用户输入的字符串使用替代密码的方式替换成密文,这里使用的密钥是4,也就是将原文的字符位置往后推4位。
返回加密密文。
2、/*解开替代密码的解密函数*/
chardesubstitute(charmessage[])//定义desubstitute函数
实现功能:
把密文中每个字符往前推4位,从而实现对替代密文的解密操作。
返回解密密文。
3、/*置换密码的函数*/
chartransform(charmessage[])//定义transform函数
实现功能:
把用户输入的原文使用置换密码的原理用二维数组进行置换操作。
返回加密后的字符串。
4、/*解开转换密码的函数*/
chardetransform(charmessage[])//定义detransform函数
实现功能:
对经置换密码加密后的密文进行解密。
返回解密后的字符串。
五、程序流程图
6、测试结果
1、替代密码加密:
2、替代密码解密:
3、置换密码加密:
4、置换密码解密:
7、分析两种算法的安全性
对替代算法来说:
由输入密钥k决定,密钥空间最大为26!
对置换算法而言:
根据你输入密钥空间的位数L决定,所有的置换可能构成一个L!
阶的对称群
我认为这两种算法都不是太好,但相比较而言,置换密码通过让几个一组排列成矩阵,然后对调其中的几列,打乱原先的排序,从而形成密文,相对而言,要比替代密码的算法难一些,因此,置换算法的安全性要比替代算法的安全性好些。
8、实验的体会总结
本次实验主要了解两种古典密码的算法,是对密码算法的初步认识。
而我这次的实验只能算是初步完成了实验要求,对于替代密码的算法,理解还比较深刻,而置换密码的算法,只是按照题目所给出的要求,只写出了密钥为6的程序,没有继续深入,将密钥的值更改,还有待提高。
9、实验代码
#include
#include
#include
#defineMAX1000
intmain()
{
charsubstitute(chara[]);//替代加密算法的实现
chartransform(charb[]);//置换加密算法的实现
chardesubstitute(charc[]);//替换解密算法的实现
chardetransform(chard[]);//置换解密算法的实现
charmessage[MAX];
charalgorithm;//用于选择算法
printf("*******************************\n");
printf("*欢迎进入古典算法的实现*\n");
printf("*请按照提示选择你需要的算法*\n");
printf("*1.替换加密2.替换解密*\n");
printf("*3.置换加密4.置换解密*\n");
printf("*(按q键退出程序)*\n");
printf("*******************************\n");
printf("请输入原文:
");
gets(message);
printf("\n");
printf("您刚输入的原文是:
\n");
puts(message);
printf("请做出选择:
");
scanf("%c",&algorithm);
while(algorithm!
='1'&&algorithm!
='2'&&algorithm!
='q'&&algorithm!
='Q'&&algorithm!
='3'&&algorithm!
='4')
{
printf("对不起,你所输入错误,请重新输入.\n");
scanf("%c",&algorithm);//接受回车字符
scanf("%c",&algorithm);//接受选择出来的算法
}
if(algorithm=='1')
{
*message=substitute(message);
printf("加密后,密文是:
\n");//输出加密后的文件内容
puts(message);
printf("\n");
}
elseif(algorithm=='2')
{
*message=desubstitute(message);
printf("解密后,明文是:
\n");
puts(message);
printf("\n");//输出解密后的文件内容
}
elseif(algorithm=='3')
{
*message=transform(message);
printf("加密后,密文是:
\n");//输出加密后的文件内容
puts(message);
printf("\n");
}
elseif(algorithm=='4')
{
*message=detransform(message);
printf("解密后,原文是:
\n");
puts(message);
printf("\n");//输出解密后的文件内容
}
elseif('q'==algorithm||'Q'==algorithm)
{
printf("退出程序!
\n");
return0;
}
getchar();
return0;
}
/*替代密文的加密函数*/
charsubstitute(charmessage[])//定义substitute函数
{
intn,i;
intk;
printf("\n\n请输入替代密钥:
");
scanf("%d",&k);
getchar();
for(n=0;n{
if(message[n]>='a'&&message[n]<='z')
{
message[n]=(message[n]-96+k+26*100)%26+64;
}
elseif(message[n]>='A'&&message[n]<='Z')
{
message[n]=(message[n]-64+k+26*100)%26+96;
}
else
{
message[n]=message[n];
}
}
return(*message);//返回密文
}
/*解开替代密文的解密函数*/
chardesubstitute(charmessage[])//定义desubstitute函数
{
intk;
intn,i;
printf("请输入代替密钥:
");
scanf("%d",&k);
getchar();
for(n=0;n{
if(message[n]>='a'&&message[n]<='z')
{
message[n]=(message[n]-96-k+26*100)%26+64;
}
elseif(message[n]>='A'&&message[n]<='Z')
{
message[n]=(message[n]-64-k+26*100)%26+96;
}
else
{
message[n]=message[n];
}
}
return(*message);//返回原文
}
/*置换密码的函数*/
chartransform(charmessage[])
{
inti,j,x,y,z,n,m;
n=strlen(message);
i=n/6;
j=n%6;//I为将要规划的行数,J为要规划的列数,m为凑成6的倍数大于或者等于n
if(j==0)//字符数刚好是6的倍数,i不变,j=6,m=6*i
{
j=6;
m=6*i;
}
elseif(j!
=0)//字符数不是6的倍数,i加1,j=6,m=6*i;
{
i=i+1;
j=6;
m=6*i;
}
chara[i][j];//用来存MESSAGE
chartemp1[i][j];
chartemp2[i][j];//申明两个数组用来作替换时用
for(x=0;x
{
for(y=0;y{
a[x][y]='';
temp1[x][y]='';
temp2[x][y]='';
}
}
if(i==1)//把字符串存入二维数组中,只有一行的情况
{
for(x=0;xa[0][x]=message[x];
}
elseif(i==2)//两行字符的情况
{
for(x=0;x<6;x++)
a[0][x]=message[x];
for(x=0;xa[1][x]=message[x+6];
}
elseif(i==3)//这里只计算最多有3行6列的内容,第三行
{
for(x=0;x<6;x++)
a[0][x]=message[x];
for(x=0;x<6;x++)
a[1][x]=message[x+6];
for(x=0;xa[2][x]=message[x+12];
}
for(z=0;z
{
temp1[z][0]=a[z][0];
}
for(z=0;z
{
temp1[z][1]=a[z][3];
}
for(z=0;z
{
temp1[z][2]=a[z][4];
}
for(z=0;z
{
temp1[z][3]=a[z][2];
}
for(z=0;z
{
temp1[z][4]=a[z][1];
}
for(z=0;z
{
temp1[z][5]=a[z][5];
}
for(z=0;z
{
temp2[z][0]=temp1[z][0];
}
for(z=0;z
{
temp2[z][1]=temp1[z][3];
}
for(z=0;z
{
temp2[z][2]=temp1[z][4];
}
for(z=0;z
{
temp2[z][3]=temp1[z][2];
}
for(z=0;z
{
temp2[z][4]=temp1[z][1];
}
for(z=0;z
{
temp2[z][5]=temp1[z][5];
}
z=0;//初始化z
for(x=0;x<6;x++)
{
for(y=0;y
{
message[z]=temp2[y][x];//将加密后的二维数组密文存入一维数组message中。
}
}
message[m]='\0';
return(*message);
}
/*解开转换密码的函数*/
chardetransform(charmessage[])
{
inti,j,x,y,z,n,m;
n=strlen(message);
i=n/6;
j=n%6;//I为将要规划的行数,J为要规划的列数,m为6的倍数大于等于n
if(j==0)//字符数刚好是6的倍数,i不变,j=6,m=6*i
{
j=6;
m=6*i;
}
elseif(j!
=0)//字符数不是6的倍数,i加1,j=6,m=6*i;
{
i=i+1;
j=6;
m=6*i;
}
chara[i][j];//用来存MESSAGE
chartemp1[i][j];
chartemp2[i][j];//申明两个数组用来作替换时用
for(x=0;x
{
for(y=0;y{
a[i][j]='';
temp1[i][j]='';
temp2[i][j]='';
}
}
if(i==1)//把字符串存入二维数组中,只有一行的情况
{
for(x=0;xa[0][x]=message[x];
}
elseif(i==2)//两行字符的情况,6<=n<12
{
for(x=0;x<2;x++)
a[x][0]=message[x];
for(x=0;x<2;x++)
a[x][1]=message[x+2];
for(x=0;x<2;x++)
a[x][2]=message[x+4];
for(x=0;x<2;x++)
a[x][3]=message[x+6];
for(x=0;x<2;x++)
a[x][4]=message[x+8];
for(x=0;x<2;x++)
a[x][5]=message[x+10];
}
elseif(i==3)//这里只计算最多有3行6列的内容
{
for(x=0;x<3;x++)
a[x][0]=message[x];
for(x=0;x<3;x++)
a[x][1]=message[x+3];
for(x=0;x<3;x++)
a[x][2]=message[x+6];
for(x=0;x<3;x++)
a[x][3]=message[x+9];
for(x=0;x<3;x++)
a[x][4]=message[x+12];
for(x=0;x<3;x++)
a[x][5]=message[x+15];
}
for(z=0;z
{
temp1[z][0]=a[z][0];
}
for(z=0;z
{
temp1[z][1]=a[z][3];
}
for(z=0;z
{
temp1[z][2]=a[z][4];
}
for(z=0;z
{
temp1[z][3]=a[z][2];
}
for(z=0;z
{
temp1[z][4]=a[z][1];
}
for(z=0;z
{
temp1[z][5]=a[z][5];
}
for(z=0;z
{
temp2[z][0]=temp1[z][0];
}
for(z=0;z
{
temp2[z][1]=temp1[z][3];
}
for(z=0;z
{
temp2[z][2]=temp1[z][4];
}
for(z=0;z
{
temp2[z][3]=temp1[z][2];
}
for(z=0;z
{
temp2[z][4]=temp1[z][1];
}
for(z=0;z
{
temp2[z][5]=temp1[z][5];
}
z=0;
for(x=0;x
{
for(y=0;y<6;y++,z++)
{
message[z]=temp2[x][y];//将加密后的二维数组密文存入一维数组message中。
}
}
message[m]='\0';
return(*message);
}