加密与解密

加密与解密是通信中最常用的数据转换手段,先了解加密与解密的基本过程;

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

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

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

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

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
#include
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

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

请输入明文:It is the man not the method that solves the problem
请输入密钥(3~4位整数):2017
加密的密文:

以上程序把文本字符分为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
#include
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[n]='\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[n]='\0';
   printf("解密为明文:");    /*输出解密文*/
   puts(c);
   printf("\n");
}

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

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

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

加密解密是一个专业性很强的系统工程,内容丰富,算法精深,如果读者对专业加密解密算法有兴趣,请参阅相关的专业教程;

你可能感兴趣的:(致美C程序,数据转换)