实验一、密码学基本算法的实现(一)

上机实验报告(一)

实验课程:应用密码学   

实验时间:20XX年9月26日

任课教师:***

班级:11级信息与计算科学专业1班

姓名:刘静**

学号:***

一、实验名称: 密码学基本算法的实现(一)

二、实验目的

学习常见的古典密码学算法,通过编程实现替代密码算法和置换密码算法,加深对古典密码体制的了解,为深入学习密码学奠定基础。

三、实验要求

1、在D盘建立一个自己的文件夹;

2、开启软件平台—Visual C++6.0,在此环境下进行编程实验;

3、将题目、你输入的命令、程序及运行结果保存在word文件中,作为作业提交;

4、若出现错误,修改、运行直到输出正确结果。

四、报告正文(文档,数据,模型,程序,图形)

1、编写程序实现仿射加密和Playfair密码。通过讨论分析单表代替密码和多表代替密码算法的功能需求,详细设计实现代替密码算法的数据结构和流程,给出测试用例和测试步骤,得出测试和结论。算法的实现程序必须提供加密和解密两个接口:int encrypt()和int decrypt()。当加密或者解密成功时返回CRYPT_OK,失败时返回CRYPT_ERROR。

/**********加密的实现**********/

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

char book[5][5]={' '}; //密码本.设为全局变量.

/******************************

*查找在密码本中的位置。

*******************************/

int findlocation(char m,int *t)

{

int i,j;

int temp; //表示行数.

for(i=0;i<5;i++)

for(j=0;j<5;j++)

if(m==book[i][j])

{

*t=j;

temp=i;

i=5; //不必再循环。

j=5;

}

return temp; //返回行数。

}

/*************************

*密码输出函数

**************************/

void out_put(int s0,int t0,int s1,int t1)

{

char c[2]={' '};

if(s0==s1) //同一行。

{

c[0]=book[s0][(t0+1)%5];

c[1]=book[s0][(t1+1)%5];

}

else if(t0==t1) //同一列.

{

c[0]=book[(s0+1)%5][t0];

c[1]=book[(s1+1)%5][t0];

}

else //不同行不同列.

{

c[0]=book[s0][t1];

c[1]=book[s1][t0];

}

printf("%c",c[0]); //输出已加密的两个字符.

printf("%c",c[1]);

}

/********************************

*对明文加密.

*********************************/

void Encrypt()

{

char m[2]={' '}; //明文数组.

char temp,ch;

char flag1,flag2; //用来标志上一轮中处理的第二个字母,提高解密精度.

int s0,t0,s1,t1,i; //两个字符的位置参数.

temp=' '; //初始化为空字符.

i=0; //控制变量.

flag1=m[1]; //初始化.

while((ch=getchar())!='\n')

{

if(ch==' ') //如果输入的是空格跳过去.

continue;

if(ch=='j') //如果输入的是j则当作i处理.

ch='i';

m[i++]=ch; //赋入数组.

if(temp!=' ') //如果上一步操作中有两个相同的字母.

{

m[1]=m[0];

m[0]=temp;

temp=' ';

i=2; //标志变量,不必再输入下一个.

}

if(i!=2) //数组赋满,则跳过.

continue;

i=0;

if(m[0]==m[1]) //如果两个字母相同,则处理成不相同的.

{

temp=m[1];

flag2='x';

while(m[1]==m[0]||m[1]==flag1)

m[1]=flag2++;

}

flag1=m[1];

s0=findlocation(m[0],&t0); //列值传递的是地址.

s1=findlocation(m[1],&t1);

m[0]=' ';

out_put(s0,t0,s1,t1); //在密码本中打印密码.

}

/*不会出现的情况是:temp!=' ' && m[0]!='\n' */

if(temp!=' '||m[0]!=' ') //此处是为了防止出现什么也没有输入的情况。

{

if(m[0]==' '&&temp!=' ') //最后刚好剩余一位.

{

m[0]=temp;

m[1]=flag2='x';

while(m[1]==m[0]||m[1]==flag1)

m[1]=flag2++;

}

if(temp==' '&&m[0]!=' ') //最后剩余一位并且上一轮中有相同的字母.

{

//m[0]=temp;

m[1]=flag2='x';

while(m[1]==m[0]||m[1]==flag1)

m[1]=flag2++;

}

s0=findlocation(m[0],&t0);

s1=findlocation(m[1],&t1);

out_put(s0,t0,s1,t1);

}

}

/*************************

*构造密码本

**************************/

void createbook()

{

char key; //key密钥

int temp[25]={' '}; //临时数组,记录密钥中出现字母的位置.

int t,flag=0; //辅助变量. flag用于定位新出现字母的位置.

/*************************************

*构造密码本.

**************************************/

for(t=0;t<25;t++) //对整型数组赋值.

temp[t]=26;

while((key=getchar())!='\n') //此处要极其注意,用换行符表示其结束.

{

if(key<'j')

t=key-'a'; //t表示字母相对于数组的位置.

if(key>'j')

t=key-'a'-1;

if(temp[t]==26) //若未出现过,则记录其位置.

temp[t]=flag++;

}

for(t=0;t<25;t++) //完善字母的顺序,并映射到密码本。

{

if(temp[t]==26) //将未出现过的字母按字母表顺序在数组中编号.

temp[t]=flag++;

if(t+'a'<'j') //按照次序将临时数组中的字母映射到密码本中.

book[temp[t]/5][temp[t]%5]=t+'a'; //处理小于i的情况。

else

book[temp[t]/5][temp[t]%5]=t+'a'+1; //处理大于j的情况。

}

for(t=0;t<25;t++) //打印。

printf("%d ",temp[t]);

printf("\n");

for(t=0;t<25;t++) //打印。

{

printf(" %c",book[t/5][t%5]);

if(!((t+1)%5))

printf("\n");

}

}

/*******************************

*主函数

********************************/

int main()

{

createbook(); //构造密码本。

Encrypt(); //进行加密。

printf("\n");

return 0;

}

/**********************

*解密

*密码本构造函数相同.

*部分不同.

***********************/

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

char book[5][5]={' '}; //密码本.设为全局变量.

/******************************

*查找在密码本中的位置。

*******************************/

int findlocation(char m,int *t)

{

int i,j;

int temp; //表示行数.

for(i=0;i<5;i++)

for(j=0;j<5;j++)

if(m==book[i][j])

{

*t=j;

temp=i;

i=5; //不必再循环。

j=5;

}

return temp; //返回行数。

}

/*************************

*密码输出函数

**************************/

void out_put(char str[1001])

{

char c[2]={' '};

char cip[1001];

int s0,t0,s1,t1;

int i,j;

i=j=0;

while(str[i]!='\0')

{

s0=findlocation(str[i++],&t0);

s1=findlocation(str[i++],&t1);

if(s0==s1) //同一行。

{

c[0]=book[s0][(t0+4)%5];

c[1]=book[s0][(t1+4)%5];

}

else if(t0==t1) //同一列.

{

c[0]=book[(s0+4)%5][t0];

c[1]=book[(s1+4)%5][t0];

}

else //不同行不同列.

{

c[0]=book[s0][t1];

c[1]=book[s1][t0];

}

cip[j++]=c[0];

cip[j++]=c[1];

}

j=strlen(str);

i=0;

while(i+2<j)

{

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

if(cip[i]!=cip[i+2])

i++;

else

i+=2;

}

if(i!=j-1)

printf("%c",cip[i++]);

printf("%c\n",cip[i]);

}

/********************************

*对密文解密.

*********************************/

void Decry()

{

char str[1001];

gets(str);

if(strlen(str)%2==1)

{

printf("密文的个数不能是奇数!");

return 0;

}

else

out_put(str);

}

/*************************

*构造密码本

**************************/

void createbook()

{

char key; //key密钥

int temp[25]={' '}; //临时数组,记录密钥中出现字母的位置.

int t,flag=0; //辅助变量. flag用于定位新出现字母的位置.

/*************************************

*构造密码本.

**************************************/

for(t=0;t<25;t++) //对整型数组赋值.

temp[t]=26;

while((key=getchar())!='\n') //此处要极其注意,用换行符表示其结束.

{

if(key<'j')

t=key-'a'; //t表示字母相对于数组的位置.

if(key>'j')

t=key-'a'-1;

if(temp[t]==26) //若未出现过,则记录其位置.

temp[t]=flag++;

}

for(t=0;t<25;t++) //完善字母的顺序,并映射到密码本。

{

if(temp[t]==26) //将未出现过的字母按字母表顺序在数组中编号.

temp[t]=flag++;

if(t+'a'<'j') //按照次序将临时数组中的字母映射到密码本中.

book[temp[t]/5][temp[t]%5]=t+'a'; //处理小于i的情况。

else

book[temp[t]/5][temp[t]%5]=t+'a'+1; //处理大于j的情况。

}

for(t=0;t<25;t++) //打印。

printf("%d ",temp[t]);

printf("\n");

for(t=0;t<25;t++) //打印。

{

printf(" %c",book[t/5][t%5]);

if(!((t+1)%5))

printf("\n");

}

}

/*******************************

*主函数

********************************/

int main()

{

createbook(); //构造密码本。

Decry(); //进行加密。

printf("\n");

return 0;

}

相关推荐