凯撒密文的破解编程实现

由于它是一种对称密码体制,加解密的密钥是一样的,下边简单说明一下加解密加密过程:
         密文:C=M+K  (mod 26)
解密过程:
         明文:M=C-K  (mod 26)
破解时主要利用了概率统计的特性,E字母出现的概率最大。

下面重点说一下解密的程序实现:我是用C写的,在VC6.0下调试运行正确

ContractedBlock.gif ExpandedBlockStart.gif Code
  1 #include"stdio.h"
  2 #include"ctype.h"
  3 #include"stdlib.h"
  4 
  5 
  6 main(int argc ,char *argv[])
  7 {
  8 
  9 FILE *fp_ciper,*fp_plain;                   //密文与明文的文件指针
 10 char ch_ciper,ch_plain;
 11 int i,temp=0;                               //i用来存最多次数的下标
 12                                              //temp用在求最多次数时用
 13 int key;                                    //密钥
 14 int j;
 15 int num[26];                                //保存密文中字母出现次数
 16 
 17 for(i = 0;i < 26; i++)
 18      num[i] = 0;                             //进行对num[]数组的初始化
 19 
 20 printf("======================================================\n");
 21 printf("------------------破解凯撒密文--------------------\n");
 22 printf("======================================================\n");
 23 
 24 if(argc!=3)
 25 {
 26      printf("此为KAISER解密用法:[文件名] [密文路径] [明文路径]\n");
 27      printf("如:decryption F:\ciper_2_1.txt F:\plain.txt\n");
 28 }                                         //判断程序输入参数是否正确
 29 
 30 
 31 if((fp_ciper=fopen(argv[1],"r"))==NULL)
 32 {
 33      printf("打开密文出错!解密失败\n");
 34      exit(0);
 35 }
 36 while((ch_ciper=fgetc(fp_ciper))!=EOF)
 37 switch(ch_ciper)
 38 
 39      case 'A':num[0]=num[0]+1;  break;     //统计密文各字母出现次数
 40      case 'B':num[1]=num[1]+1;  break;     //与上同,下边一样
 41      case 'C':num[2]=num[2]+1;  break;
 42      case 'D':num[3]=num[3]+1;  break;
 43      case 'E':num[4]=num[4]+1;  break;
 44      case 'F':num[5]=num[5]+1;  break;
 45      case 'G':num[6]=num[6]+1;  break;
 46      case 'H':num[7]=num[7]+1;  break;
 47      case 'I':num[8]=num[8]+1;  break;
 48      case 'J':num[9]=num[9]+1;  break;
 49      case 'K':num[10]=num[10]+1;break;
 50      case 'L':num[11]=num[11]+1;break;
 51      case 'M':num[12]=num[12]+1;break;
 52      case 'N':num[13]=num[13]+1;break;
 53      case '0':num[14]=num[14]+1;break;
 54      case 'P':num[15]=num[15]+1;break;
 55      case 'Q':num[16]=num[16]+1;break;
 56      case 'R':num[17]=num[17]+1;break;
 57      case 'S':num[18]=num[18]+1;break;
 58      case 'T':num[19]=num[19]+1;break;
 59      case 'U':num[20]=num[20]+1;break;
 60      case 'V':num[21]=num[21]+1;break;
 61      case 'W':num[22]=num[22]+1;break;
 62      case 'X':num[23]=num[23]+1;break;
 63      case 'Y':num[24]=num[24]+1;break;
 64      case 'Z':num[25]=num[25]+1;break;
 65      
 66 }
 67 fclose(fp_ciper);
 68 
 69 for(i=0;i<26;i++)
 70      if(num[i]>temp)
 71      {
 72          j=i;                               // 求出最大次数的下下标 
 73          temp=num[i];      
 74      }
 75 if(j<5)
 76       key=(j+1+26)-5;                       //是按字母表的第几位计算
 77                                             //而不是按下标,故加1
 78                                             //5是指E在字母表中的位序
 79 else
 80       key=(j+1)-5;
 81 
 82 
 83 if((fp_ciper=fopen(argv[1],"r"))==NULL)
 84 {
 85      printf("再次打开密文出错!解密失败\n");
 86      exit(0);
 87 }                                         //再次打开密文,进行解密
 88 if((fp_plain=fopen(argv[2],"w"))==NULL)
 89 {
 90      printf("打开或建立明文文件出错!解密失败\n");
 91      exit(0);
 92 }                                         //把明文存到此文件
 93 while((ch_ciper=fgetc(fp_ciper))!=EOF)
 94 {
 95 if(ch_ciper > 'E')
 96 ch_plain=(((ch_ciper-'A'-key)%26)+'A');    //解密
 97 else
 98 ch_plain=(((ch_ciper-'A'-key+26)%26)+'A'); //解密
 99 ch_plain=tolower(ch_plain);                //把大写明文转化为小写
100 fputc(ch_plain,fp_plain);                  //把明文写到文件文件plain
101 }
102 fclose(fp_ciper);
103 fclose(fp_plain);
104 printf("解密成功,密钥KEY=%d,明文已保存到文件中,谢谢使用!\n",key);
105 
106 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值