古典密码实验报告.docx
《古典密码实验报告.docx》由会员分享,可在线阅读,更多相关《古典密码实验报告.docx(30页珍藏版)》请在冰豆网上搜索。
古典密码实验报告
工程大学
实验报告
实验名称:
古典密码算法
班级:
学号:
姓名:
实验时间:
2014年4月
成绩:
指导教师:
实验室名称:
工程大学实验室与资产管理处制
一、实验名称古典密码算法
二、实验目的
通过编程实现经典的代替密码算法和置换密码,包括移位密码、维吉尼亚密码、周期置换密码、列置换密码,加深对代替技术的了解,为现代分组密码实验奠定根底。
三、实验环境〔实验所使用的器件、仪器设备名称及规格〕
运行Windows或Linux操作系统的PC机,具有gcc(Linux)、VC〔Windows〕等C语言编译环境。
四、实验任务及其要求
〔1〕根据实验原理局部对移位密码的介绍,自己创立明文信息,并选择一个密钥,编
写移位密码的实现程序,实现加密和解密操作。
〔2〕根据实验原理局部对维吉尼亚密码的介绍,自己创立明文信息,并选择一个密钥,
编写维吉尼亚密码的实现程序,实现加密和解密操作。
〔3〕根据实验原理局部对周期置换密码的介绍,自己创立明文信息,并选择一个密钥,
编写周期置换密码的实现程序,实现加密和解密操作。
〔4〕根据实验原理局部对列置换密码的介绍,自己创立明文信息,并选择一个密钥,
编写列置换密码的实现程序,实现加密和解密操作。
五、实验设计〔包括原理图、真值表、分析及简化过程、卡诺图、源代码等〕
1.移位密码
移位密码〔ShiftCipher〕是一种典型的单表替代密码,也称为加法密码。
移位密码的加密方法就是将明文中的每个字母用其在字母表后面的第k个字母替代,它的加密过程可以表示为:
c=(m+k)modn
其中,m为明文字母在字母表中的位置数;n为字母表中的字母总数;k为密钥;c为密文字母在字母表中对应的位置数。
相应的,移位密码的解密过程可以表示为:
m=(c-k)modn
移位密码的一个典型代表就是凯撒密码〔CeaserCipher〕,它是k=3时的移位密码。
使用英文字母表的撒密码的加〔解〕密可以表示为:
m=(c+3)mod26m=(c-3)mod26,例如,
明文:
attacksatnineam
密钥:
3
加密:
将明文分组对每一个密文字母,依英文字母表,用其右的第3个字母代替
密文:
dwwdfnvdwqlqhdp
另外,使用凯撒密码加密后的密文“dwwdfnvdwilyhsp〞,其明文为“attacksatfivepm〞。
2.维吉尼亚密码
维吉尼亚密码〔VigenereCipher〕是一种多表代替密码,其本质是周期移位密码。
维吉尼亚密码的〔用户〕密钥为一含有d个字母的有限字母序列k=k0k1…kd-1
加密时,首先将用户密钥进展周期扩展〔周期为d〕,扩展后的无限字母序列称为工作密钥,记为K=K0K1…Ki…其中Ki=Kimodd,i=0,1,…
当d=1时,维吉尼亚密码就是移位密码。
对于含有l个字母的明文,维吉尼亚加密过程可以表示为:
ci=(mi+Ki)modn其中,M=m0m1…mi…ml-1为明文,C=c0c1…ci…cl-1为密文,K=K0K1…Ki…Kl-1为工作钥,n为明文字母表的长度,l为明文长度〔含有字母的数目〕。
例如,使用用户钥cat,对明文“vigenerecipher〞进展维吉尼亚加密。
此时,n=26〔对应英文字母表〕,用户钥c=3、a=0、t=19,得到的密文为“xizgnxtevkpagr〞。
置换〔Permutation〕是古典密码中另一种根本的处理技巧,就是将明文中的字母重新排列,字母本身不变,只是改变其位置。
置换密码〔SubstitutionCipher〕就是使用置换法进展加解密的密码算法,也称为换位密码。
置换密码的密钥是一个置换,它表示了明文字母在密文中出现的位置。
例如,使用密钥π=(3421),对明文“ming〞进展加密,得到的密文为“ngim〞。
3.周期置换密码
周期置换密码是将明文字母按一定长度m进展分组,把每个分组中的字母按1,2,…,m的一个置换π重排位置次序来得到密文的一种加密方法。
其中的密钥就是置换π,在π的描述中包含了分组长度的信息。
解密时,对密文字符按长度m进展分组,并按π的逆置换π−1
把每组字符重排位置次序来得到明文。
例如,
明文:
mingchenjiudianfadongfangong
加密密钥:
3421〔i=1,2,3,4的一个置换π(i)=3,4,2,1〕
加密:
将明文分组〔4个字母一组〕,然后根据加密密钥给定的置换,对每个明文分组进展置换
mingchenjiudianfadongfangong
ngimenhcudijnfaiondaanfgngog
密文:
ngimenhcudijnfaiondaanfgngog
解密密钥:
4312〔3412的逆置换〕
4.列置换密码
列置换密码也称为矩阵置换密码。
其加解密方法如下:
把明文字符以固定的宽度m(分组长度)水平地(按行)写在一纸上,按1,2,…,m的一个置换π交换列的位置次序,再按垂直方向(即按列)读出即得密文。
解密就是将密文按一样的宽度m垂直在写在纸上,按置换π的逆置换π−1交换列的位置次序,然后水平地读出得到明文。
置换π就是密钥。
例如,
明文:
mingchenjiudianfadongfangong
密钥:
yulanhua
加密:
去掉密钥重复字母得yulanh,得到密钥字母顺序653142
得出距阵列数为6,将明文按行填充距阵
按列〔依顺序〕写出距阵中的字母。
密文:
giffghddn0njngncuaa0inanomeiog〔其中0为无效字符〕
解密:
加密的逆过程
六、实验步骤
通过实验分析,将各个古典密码算法编写出来,然后编写一个主函数。
调试,验证加密解密正确性。
#include
#include
#defineCRYPT_OK1
#defineCRYPT_ERROR0
#defineMAXSIZE100
voidShiftCipher();
voidVigenereCipher();
voidCycleCipher();
voidColCipher();
voidmain()
{
intop=0;
while
(1)
{
printf("WhichCipherwouldyouwant?
:
1.Shift2.Vig3.Cyc4.Col:
\n");
scanf("%d",&op);
fflush(stdin);
switch(op)
{
case1:
{ShiftCipher();}break;
case2:
{VigenereCipher();}break;
case3:
{CycleCipher();}break;
case4:
{ColCipher();}break;
}
}
}
//主函数
//列置换置换密码
intColencrypt(char*plain,char*cipher,char*key);//列置换置换密码加密算法
intColdecrypt(char*plain,char*cipher,char*key);//列置换置换密码解密算法
voidColCipherEncrypt();//列置换置换密码加密调用
voidColCipherDecrypt();//列置换置换密码解密调用
voidColCipher();//列置换置换密码模块调用
intfix(char*m,intT);//字符串补齐修正
voidColCipher()
{
intop=0;
while
(1)
{
fflush(stdin);
printf("__This_is_Coloum_Cipher_Process____________________\n");
printf("1forencrypt,2fordecrypt:
");
scanf("%d",&op);
getchar();
switch(op)
{
case1:
{ColCipherEncrypt();}break;
case2:
{ColCipherDecrypt();}break;
default:
{printf("ErrorInput\n");}
}
}
}
//列置换置换密码模块调用
voidColCipherEncrypt()
{
charp[MAXSIZE],c[MAXSIZE],k[MAXSIZE];
//定义变量
printf("PleaseInputthePlaintext:
\n");
gets(p);
fflush(stdin);
printf("PleaseInputtheColKey:
(连续整数序列置换)\n");
gets(k);
//获取明文&密钥
fix(p,strlen(k));
//补齐空格
Colencrypt(p,c,k);
//调用加密函数
printf("Chipertext:
\n%s",c);
getchar();
}
//列置换置换密码加密调用
voidColCipherDecrypt()
{
charp[MAXSIZE],c[MAXSIZE],k[MAXSIZE],flag,abc[27];
inti,temp;
//定义变量
printf("PleaseInputtheCiphertext:
\n");
gets(c);
printf("DoYouKnowtheKey?
y/n:
");
fflush(stdin);
scanf("%c",&flag);
getchar();
switch(flag)
{
case'y':
//假设知道密钥那么直接经行解密
{
printf("PleaseInputtheColKey:
\n");
gets(k);
//获取密钥
fix(c,strlen(k));
Coldecrypt(p,c,k);
//调用函数
printf("Plaintext:
\n%s\n",p);
}break;
case'n':
//不知道密钥那么对文本进展字母统计分析
{
printf("ThenIcan'thelpyou!
\n");
};break;
default:
{printf("ERROR\n");}
}
}
//列置换置换密码解密调用
intColencrypt(char*plain,char*cipher,char*key)
{
inti,r,T,n,j;
chartemp[MAXSIZE];
i=0;
T=strlen(key);
while(plain[i]!
='\0')
{
r=i%T;
cipher[i]=plain[i-r+(key[r]-'0')-1];
i++;
}
cipher[i]='\0';
n=strlen(cipher)/strlen(key);
for(i=0;i{
for(j=0;j{
temp[i]=cipher[T*j+i%T];
}
}
temp[strlen(cipher)]='\0';
returnCRYPT_OK;
}
//列置换置换密码加密算法
intColdecrypt(char*plain,char*cipher,char*key)
{
inti,r,T,n,j;
chartemp[MAXSIZE];
i=0;
T=strlen(key);
while(cipher[i]!
='\0')
{
r=i%T;
plain[i]=cipher[i-r+(key[r]-'0')-1];
i++;
}
plain[i]='\0';
n=strlen(plain)/strlen(key);
for(i=0;i{
for(j=0;j{
temp[i]=plain[T*j+i];
}
}
temp[strlen(plain)]='\0';
plain=temp;
returnCRYPT_OK;
}
//列置换置换密码解密算法
//移位密码
intShiftEncrypt(char*plain,char*cipher,intkey);//移位密码加密算法
intShiftDecrypt(char*plain,char*cipher,intkey);//移位密码解密算法
voidShiftCipherEncrypt();//移位密码加密调用
voidShiftCipherDecrypt();//移位密码解密调用
voidShiftCipher();//移位密码模块调用
voidShiftCipher()
{
intop=0;
while
(1)
{
fflush(stdin);
printf("_This_is_Shift_Cipher_Process_________________________\n");
printf("1forencrypt,2fordecrypt:
");
scanf("%d",&op);
getchar();
switch(op)
{
case1:
{ShiftCipherEncrypt();}break;
case2:
{ShiftCipherDecrypt();}break;
default:
{printf("ErrorInput\n");}
}
}
}
//移位密码模块调用
voidShiftCipherEncrypt()
{
charp[MAXSIZE],c[MAXSIZE];
intkey=0;
//定义变量
printf("PleaseInputthePlaintext:
\n");
gets(p);
printf("PleaseInputtheShiftKey:
\n");
scanf("%d",&key);
//获取必要信息
ShiftEncrypt(p,c,key);
//调用函数
printf("Chipertext:
\n%s\n",c);
getchar();
}
//移位密码加密调用
voidShiftCipherDecrypt()
{
charp[MAXSIZE],c[MAXSIZE],flag;
intkey=0;
inti;
//定义变量
printf("PleaseInputtheCiphertext:
\n");
gets(c);
printf("DoYouKnowtheKey?
y/n:
");
fflush(stdin);
scanf("%c",&flag);
getchar();
switch(flag)
{
case'y':
{
printf("PleaseInputtheShiftKey[0-26]:
\n");
scanf("%d",&key);
//获取必要信息
ShiftDecrypt(p,c,26-key);
//调用函数
printf("Plaintext:
\n%s\n",p);
getchar();
}break;
case'n':
{
for(i=25;i>0;i--)
{
ShiftDecrypt(p,c,i);
printf("PlaintextShiftBy%2dis:
%s\n",26-i,p);
}
};break;
default:
{printf("ERROR\n");}
}
}
//移位密码解密调用
intShiftEncrypt(char*plain,char*cipher,intkey)
{
inti=0;
while(plain[i]!
='\0')
{
if(plain[i]>='A'&&plain[i]<='Z')
{
cipher[i]=(plain[i]+key-'A')%26+'A';
}
else
{
if(plain[i]>='a'&&plain[i]<='z')
{
cipher[i]=(plain[i]+key-'a')%26+'a';
}
else
cipher[i]=plain[i];
}
i++;
}
cipher[i]='\0';
returnCRYPT_OK;
}
//移位密码加密算法
intShiftDecrypt(char*plain,char*cipher,intkey)
{
inti=0;
while(cipher[i]!
='\0')
{
if(cipher[i]>='A'&&cipher[i]<='Z')
{
plain[i]=(cipher[i]-'A'+key)%26+'A';
}
else
{
if(cipher[i]>='a'&&cipher[i]<='z')
{
plain[i]=(cipher[i]-'a'+key)%26+'a';
}
else
{plain[i]=cipher[i];}
}
i++;
}
plain[i]='\0';
returnCRYPT_OK;
}
//移位密码解密算法
//弗吉尼亚密码
intVigenereencrypt(char*plain,char*cipher,char*key);//弗吉尼亚密码加密算法
intVigeneredecrypt(char*plain,char*cipher,char*key);//弗吉尼亚密码解密算法
voidVigenereCipherEncrypt();//弗吉尼亚密码加密调用
voidVigenereCipherDecrypt();//弗吉尼亚密码解密调用
voidVigenereCipher();//弗吉尼亚密码模块调用
voidStatic(char*c);//密文字母频率统计模块
voidVigenereCipher()
{
intop=0;
while
(1)
{
fflush(stdin);
printf("__This_is_Vigenere_Cipher_Process_____________________\n");
printf("1forencrypt,2fordecrypt:
");
scanf("%d",&op);
getchar();
switch(op)
{
case1:
{VigenereCipherEncrypt();}break;
case2:
{VigenereCipherDecrypt();}break;
default:
{printf("ErrorInput\n");}
}
}
}
//弗吉尼亚密码模块调用
voidVigenereCipherEncrypt()
{
charp[MAXSIZE],c[MAXSIZE],k[MAXSIZE];
//定义变量
printf("PleaseInputthePlaintext:
\n");
gets(p);
fflush(stdin);
printf("PleaseInputtheVigenereKey:
(lowcase)\n");
gets(k);
//获取必要信息
Vigenereencrypt(p,c,k);
//调用函数
printf("Chipertext:
\n%s",c);
getchar();
}
//弗吉尼亚密码加密调用
voidVigenereCipherDecrypt()
{
charp[MAXSIZE],c[MAXSIZE],k[MAXSIZE],flag,abc[27];
inti,temp;
//定义变量
printf("PleaseInputtheCiphertext:
\n");
gets(c);
printf("DoYouKnowtheKey?
y/n:
");
fflush(stdin);
scanf("%c",&flag);
getchar();
switch(flag)
{
case'y':
//假设知道密钥那么直接经行解密
{
printf("PleaseInputtheVigenereKey:
\n");
gets(k);
//获取密钥
Vigeneredecrypt(p,c,k);
//调用函数
printf("Plaintext:
\n%s\n",p);
}break;
case'n':
//不知道密钥那么对文本进展字母统计分析
{
Static(c);
};break;
default:
{printf("ERROR\n");}
}
}
//弗吉尼亚密码解密调用
intVigenereencrypt(char*plain,char*cipher,char*key)
{
inti=0;
intT;
T=strlen(key);
printf("%d",T);
while(plain[i]!
='\0')
{
if(plain[i]>='A'&&plain[i]<='Z')
{
cipher[i]=(plain[i]+key[i%T]-'A'-'a')%26+'A';
}
else
{
if(plain[i]>='a'&&plain[i]<='z')
{
cipher[i]=(plain[i]+key[i%T]-'a'-'a')%26+'a';
}
else
cipher[i]=