您的位置:首页 > 编程语言 > C语言/C++

加密与解密

2017-01-04 14:36 731 查看
加密与解密是通信中最常用的数据转换手段,先了解加密与解密的基本过程;

加密:应用加密算法与密钥对明文(尚未加密的原文)实施加密,转换成密文发送

解密:接收到密文后,应用相应算法与同一密钥对密文解密,转换为明文

加密与解密的双方根据事先的基本约定(包括加密算法)与所给密钥进行加密或解密,而第三方不知约定,即使知晓密文与密钥,也很难进行解密了解通信的内容;

试设计简单的加密与解密程序,并进行运行演示;

1.加密与解密双方事先的约定:

(1)、密钥转换为操作码;

把密钥r(约定为3~4为整数)的各位数字相加,所得的和除以4的余数再加1,得到加密操作码m;

(2)、文本字符分为三类分别加密转换;

1)、非小写英文字母加密;

明文中的所有非小写英文字母(约定为ASII码小于97的字符)加密转换为其ASII码减去(10+m)所对应的ASII字符;

2)、ASII码为偶数的小写英文字母;

若小写英文字母的ASII码为偶数,把该字母转换为其对称的英文字母(例如a与z对称,b与y对称等)后,再加上加密操作码m所对应的ASII字符;

3)、ASII码为奇数的小写英文字母;

若小写英文字母的ASII码为奇数,把该字母转换为其对称的英文字母后,再减去加密操作码m所对应的ASII字符;

2.设计要求:

设置数组char s[120]存储明文,int b[120]存储密文,int c[120]存储解密文;

(1)、密钥r的处理;

通过循环求余得r的各位数字和m,经m=m%4+1迭代得唯一的加密操作码m;

输入密钥r比较大(约定3~4位整数),这样可增加第三者试图解密的难度,实际上由密钥r所得的实际加密操作码m并不大,方便操作;

(2)、小写英文字母以外字符转换;

注意到小写英文字母的ASII码至少为97,当明文中的字符s[j]<97时根据约定进行转换b[j]=s[j]-10-m;

(3)、小写英文字母加密转换;

注意到小写英文字母的ASII码为97~122,可知明文中的字母s[j]的对称字母为(97+122)-s[j],因而字母s[j]的加密字符b[j]为:

若s[j]%2==0:b[j]=219-s[j]+m

若s[j]%2>2:b[j]=219-s[j]-m

在循环中逐个转换完毕,发布b数组即为密文;

(4)、解密转换;

解密时,根据接收到的密钥r与密文(b数组)逐个字符解密转换为明文c数组;

1)、若b[j]<87时,则c[j]=b[j]+10+m;,即c[j]为原字符s[j];

2)、若原码s[j]为偶数时,则219-s[j]为奇数,而加密时b[j]=219-s[j]+m;,因而b[j]+m=219-s[j]+2*m为奇数,即当(b[j]+m)%2>0:c[j]-219-b[j]+m;,c[j]为原字母s[j]

3)、若原码s[j]为奇数时,则219-s[j]为偶数,而加密时b[j]=219-s[j]-m;,因而b[j]+m=219-s[j]为偶数,即当(b[j]+m)%2==0:c[j]=219-b[j]-m;,c[j]为原字母s[j]

通过以上3步解密转换,所得c数组与原码s[j]完全相同,实现解密;

3.程序设计:

#include<stdio.h>
#include<string.h>
int main()
{
char s[120];
int d,j,m,n,r,b[120],c[120];
printf("请输入明文:");
gets(s);
n=strlen(s);
printf("请输入密钥(3~4位整数):");
scanf("%d",&r);               /*确定密钥*/
/*加密方实施加密*/
m=0;
d=r;
while(d>0)
{
m+=(d%10);            /*根据事先约定把密钥r转换为加密操作码m*/
d=d/10;
}
m=m%4+1;
for(j=0;j<=n-1;j++)
if(s[j]<97)
b[j]=s[j]-10-m;    /*把明文字符逐个加密到b数组*/
else if(s[j]%2==0)
b[j]=219-s[j]+m;
else
b[j]=219-s[j]-m;
printf("加密的密文:");
for(j=0;j<=n-1;j++)
printf("%c",b[j]);
printf("\n");
/*接收方实施解密*/
m=0;
d=r;
while(d>0)
{
m+=(d%10);            /*根据事先约定把密钥r转换为加密操作码m*/
d=d/10;
}
m=m%4+1;
for(j=0;j<=n-1;j++)
if(b[j]<87)
c[j]=b[j]+10+m;
else if((b[j]+m)%2>0)
c[j]=219-b[j]+m;   /*把密文字符逐个解密到c数组*/
else
c[j]=219-b[j]-m;
printf("解密为明文:");
for(j=0;j<n-1;j++)
printf("%c",c[j]);    /*输出解密明文*/
printf("\n");
}


4.程序运行示例与说明:

请输入明文:It is the man not the method that solves the problem
请输入密钥(3~4位整数):2017
加密的密文:<j!!oe!!jvs!!kwp!!pij!!jvs!!ksjviz!!jvwj!!eirhse!!jvs!!nli|rsk!
解密为明文:It is the man not the method that solves the problem


以上程序把文本字符分为3类进行加密解密,应该说有一定的防破解功能,其中大写字母I是按“其他字符”处理的;

以上加密只根据字符本身的特性,使得明文中相同的字符在密文中也是相同的字符,例如,明文中有8个“t”,在密文中对应8个“j”;明文中有10个空格,在密文中对应10个“!!”,为改变这一在加密中的低级重复的现象,下面对密钥的处理与加密过程实施进一步的改进;

5.改进加密算法:

密钥加大至5~6位整数,同时加大对密钥r的处理难度:用其高位数字乘其他数字之和,所得之积除以4取余数加2,得加密操作码m

加强对明文字符的加密:

(1)、第一步加密处理

把明文中的小写英文字母转换为其对称的字母,小写英文字母以外的字符ASII码全部减去15,以避免在下一步加密时发生重叠;

(2)、第二步加密处理

为改变相同字符在加密中的低级重复现象,加密时必须考虑字符在文本中的位置,

对明文中第j个字符计算t=(j+m)%(2*m),其中m为密钥r转换的加密操作码,对该字符的ASII码加m减去t,即:

b[j]=b[j]+m-(j+m)%(2*m)

注意到t=(j+m)%(2*m)可能比m大,也可能比m小,即明文中的字符有些增加,有些减少,以增加对加密的破解难度;

解密是加密的逆过程,逐个字符恢复到源码即可;

(3)、程序设计

#include<stdio.h>
#include<string.h>
int main()
{
char b[120],c[120];
int j,m,n;
long d,r;
char s[]="Couplet:放鹤去寻三岛客,任人来看四时花。";
n=strlen(s);            /*输入明文*/
printf("请输入密钥(5~6位整数):");
scanf("%d",&r);         /*确定密钥*/
/*加密方实施加密*/
m=0;
d=r;
while(d>=10)
{
m+=(d%10);           /*根据事先约定把密钥r转换为加密操作码m*/
d=d/10;
}
m=(d*m)%4+2;
for(j=0;j<=n-1;j++)     /*加密第一步处理*/
if(s[j]<97)
b[j]=s[j]-15;
else
b[j]=219-s[j];
for(j=0;j<=n-1;j++)
b[j]=b[j]+m-(j+m)%(2*m);   /*加密第二步处理*/
b
='\0';
printf("加密的密文:");
puts(b);                /*发布密文*/
/*接收方实施解密*/
m=0;
d=r;
while(d>=10)
{
m+=(d%10);           /*根据事先约定把密钥r转换为加密操作码m*/
d=d/10;
}
m=(d*m)%4+2;
for(j=0;j<=n-1;j++)     /*逐个字符分类解密*/
if(b[j]<90)
c[j]=b[j]+15-m+(j+m)%(2*m);
else
c[j]=219-b[j]+m-(j+m)%(2*m);
c
='\0';
printf("解密为明文:");    /*输出解密文*/
puts(c);
printf("\n");
}


(4)、程序运行示例与说明

请输入密钥(5~6位整数):201706
加密的密文:4khloui,ǖ箷蘑鬼ì敖枮咕唤堡拨即剑瑯敃
解密为明文:Couplet:放鹤去寻三岛客,任人来看四时花。


以上程序改变了明文的输入,且明文文本包含了汉字,因为以上加密解密操作能逐个字符通过解密恢复到原码,所以也适合对中文汉字的加密转换处理;

加密解密是一个专业性很强的系统工程,内容丰富,算法精深,如果读者对专业加密解密算法有兴趣,请参阅相关的专业教程;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息