由于它是一种对称密码体制,加解密的密钥是一样的,下边简单说明一下加解密加密过程:
密文:C=M+K (mod 26)
解密过程:
明文:M=C-K (mod 26)
破解时主要利用了概率统计的特性,E字母出现的概率最大。
下面重点说一下解密的程序实现:我是用C写的,在VC6.0下调试运行正确
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
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