这里有方法,自己看吧,比较多,呵呵
[凯撒介绍]
凯撒密码(kaiser)是罗马扩张时期朱利斯"凯撒(Julius Caesar)创造的,用于加密通过信使传递的作战命令。它将字母表中的字母移动一定位置而实现加密。
[加密原理]
凯撒密码的加密算法极其简单。其加密过程如下:
在这里,我们做此约定:明文记为m,密文记为c,加密变换记为E(k1,m)(其中k1为密钥),解密变换记为D(k2,m)(k2为解密密钥)(在这里k1=k2,不妨记为k)。凯撒密码的加密过程可记为如下一个变换:
c≡m+k mod n (其中n为基本字符个数)
同样,解密过程可表示为:
m≡c+k mod n (其中n为基本字符个数)
对于计算机而言,n可取256或128,m、k、c均为一个8bit的二进制数。显然,这种加密算法极不安全,即使采用穷举法,最多也只要255次即可破译。当然,究其本身而言,仍然是一个单表置换,因此,频率分析法对其仍是有效的。
[加密算法]
我们预定义基本字符个数为 #define MAX 128
凯撒加密函数可以表示为
[Copy to clipboard]
CODE:
char cipher(char plain_char, int key)
{
return (plain_char + key) % MAX;
};
凯撒解密函数:
[Copy to clipboard]
CODE:
char decipher(char cipher_char, int key)
{
return (cipher_char - key + MAX) % MAX;
};
加密后,原所有的ASCII码偏移key位,解密则移回key位。
如果要对一个文本文件进行加密,则只要依次逐个字符逐个字符地读取文本文件,进行加密后,逐个字符逐个字符写入密文文本文件中,即可:
[Copy to clipboard]
CODE:
FILE *fp_plaintext;
FILE *fp_ciphertext;
char plain_char;
... ...
while((plain_char=fgetc(fp_plaintext))!=EOF)
{
fputc(cipher(plain_char,key),fp_ciphertext);
}
对文件的解密也同样方法。
[破解原理]
一篇包含字符的英文文章,其各ASCII码字符出现,都有一定的频率,下面是对Google上随意搜索到的英文文章进行分析的结果,见表:
QUOTE:
=================================================
FileName : 01.txt
[1] 32: times:204
[2] 101:e times:134
[3] 116:t times:91
[4] 105:i times:87
[5] 111:o times:77
[6] 108:l times:75
[7] 97:a times:75
[8] 110:n times:69
[9] 10:
times:67
[10] 115:s times:63
=================================================
FileName : php.si.source.txt
[1] 32: times:576
[2] 101:e times:162
[3] 115:s times:153
[4] 110:n times:141
[5] 114:r times:138
[6] 105:i times:135
[7] 10:
times:134
[8] 116:t times:129
[9] 42:* times:116
[10] 111:o times:103
=================================================
FileName : work.txt
[1] 32: times:51322
[2] 101:e times:30657
[3] 116:t times:23685
[4] 97:a times:19038
[5] 111:o times:17886
[6] 105:i times:16156
[7] 110:n times:15633
[8] 114:r times:15317
[9] 115:s times:15226
[10] 104:h times:12191
=================================================
FileName : 02.txt
[1] 32: times:299
[2] 101:e times:217
[3] 110:n times:136
[4] 105:i times:133
[5] 111:o times:124
[6] 116:t times:116
[7] 97:a times:110
[8] 115:s times:98
[9] 114:r times:92
[10] 108:l times:82
=================================================
FileName : 03.txt
[1] 45:- times:404
[2] 32: times:394
[3] 101:e times:237
[4] 116:t times:196
[5] 114:r times:173
[6] 97:a times:163
[7] 105:i times:161
[8] 110:n times:153
[9] 111:o times:142
[10] 115:s times:129
=================================================
FileName : 04.txt
[1] 32: times:326
[2] 101:e times:179
[3] 116:t times:106
[4] 105:i times:101
[5] 111:o times:96
[6] 110:n times:94
[7] 97:a times:92
[8] 115:s times:78
[9] 100:d times:61
[10] 114:r times:60
=================================================
FileName : 05.txt
[1] 32: times:441
[2] 101:e times:191
[3] 111:o times:151
[4] 116:t times:120
[5] 97:a times:112
[6] 110:n times:108
[7] 105:i times:91
[8] 114:r times:84
[9] 117:u times:79
[10] 115:s times:79
有此分析可知,一篇英文文章中,出现较高频率的两个字符是 ' ' (空格) 和 'e',而且它们的ASCII码分别是32和101,差值是69。
既然凯撒密码利用的是单表替换的一种简单加密算法,所以,我们的主角, ' ' 和 'e' ,在解密后,依然会保持相同的ASCII码差值,69。
|c1 - c2| = |'e' - ' '| = |101 - 32| = 69
|m1 - m2| = | ((c1 + k) mod 256)-((c2 + k) mod 256)| = |c1 - c2| = |'e' - ' '| = 69
现在可以得到破解凯撒密码的原理了,我们统计一片经过凯撒加密的密文字符信息,在出现频率较高的字符里面寻找差值是69的2个字符,这两个必定是 ' ' 和 'e' 字符的加密字符,计算偏移量(既密钥key),通过解密运算,还原出明文。
[破解算法]
任何一片英文加密后的密文,我们统计出所有字符的个数:
[Copy to clipboard]
CODE:
#define MAX 128
... ...
FILE *fp_ciphertext;
char cipher_char;
int i; //密文文件长度,包含多少字符
unsigned int size_file=0; //申明num数组,存储各个ASCII字符在密文中出现的个数
num[MAX];
... ...
for(i = 0;i MAX; i++) //初始化num数组中的值
num[i] = 0;
... ...
while((cipher_char=fgetc(fp_ciphertext))!=EOF)
{
num[cipher_char]++;
size_file++;
}
统计出现最多次数的字符,定义#define GETTOP 10,统计最多的前10位字符:
[Copy to clipboard]
CODE:
//统计前10位
#define GETTOP 10
... ...
int temp,i,j;
int maxascii[GETNUM]; //申明maxascii数组,存储统计出的概率前10位的字符ascii码
int maxtimes[GETNUM]; //申明maxtimes数组,存储统计出的概率前10位的字符的出现次数
... ...
for(i=0;iGETTOP;i++)
{
temp=0; //临时变量temp里面来存储出现最多次数的字符的ascii码
for(j=1;jMAX;j++) //依次比较所有的字符次数,获得最多字符的ascii码
{
if(num[j]=num[temp])
temp=j;
}
maxascii[i]=temp; //把出现最多次数字符的ascii存储到相应的maxascii数组中
maxtimes[i]=num[temp]; //把最多次数字符的出现次数存储到相应的maxtimes数组中
num[temp]=0; //把最多次数字符的次数赋值成0,
//进行循环运算,同样的算法,第二次循环得到的值,肯定是出现第二多的字符
//避免了对256或128个字符进行排序的复杂运算
//当年我用汇编编写成绩排序的程序时,也用这套排序算法:-)
}
找出出现最多字符中,ASCII码差别是69的两个字符,计算出密钥key的长度:
[Copy to clipboard]
CODE:
for(i=0;iGETTOP;i++)
{
for(j=0;jGETTOP;j++)
{
if((max[i]-max[j])==69)
{
key=(max[j] - 32 + MAX ) % MAX;
printf("Key : %d\n",key);
break;
}
}
}
既然得到了密钥长度,算完成了对凯撒密码的破解了,那就进行解密吧,大功告成!
def use_list(): str_before=input("请输入明文:") str_change=str_before.lower() str_list=list(str_change) str_list_change=str_list i=0 whilei
#includestdio.h
#includeconio.h char encrypt(char ch,int n)/*加密函数,把字符向右循环移位n*/
{
while(ch=Ach=Z)
{
return (A+(ch-A+n)%26);
}
while(ch=ach=z)
{
return (a+(ch-a+n)%26);
}
return ch;
}void menu()/*菜单,1.加密,2.解密,3.暴力破解,密码只能是数字*/
{
clrscr();
printf("\n===============================================================================");
printf("\n1.Encrypt the file");
printf("\n2.Decrypt the file");
printf("\n3.Force decrypt file");
printf("\n4.Quit\n");
printf("===============================================================================\n");
printf("Please select a item:");
return;
}void logo()/*显示版权信息*/
{
printf("\nZhensoft Encryption [Version:1.0.0]");
printf("\nCopyright (C) 2004 Zhensoft Corp.\n");
printf("\n \n");
return;
}
main()
{
int i,n;
char ch0,ch1;
FILE *in,*out;
char infile[20],outfile[20];textbackground(BLACK);
textcolor(LIGHTGREEN);
clrscr();logo();
sleep(3);/*等待3秒*/menu();
ch0=getch();while(ch0!=4)
{
if(ch0==1)
{
clrscr();
printf("\nPlease input the infile:");
scanf("%s",infile);/*输入需要加密的文件名*/ if((in=fopen(infile,"r"))==NULL)
{
printf("Can not open the infile!\n");
printf("Press any key to exit!\n");
getch();
exit(0);
} printf("Please input the key:");
scanf("%d",n);/*输入加密密码*/ printf("Please input the outfile:");
scanf("%s",outfile);/*输入加密后文件的文件名*/ if((out=fopen(outfile,"w"))==NULL)
{
printf("Can not open the outfile!\n");
printf("Press any key to exit!\n");
fclose(in);
getch();
exit(0);
} while(!feof(in))/*加密*/
{
fputc(encrypt(fgetc(in),n),out);
} printf("\nEncrypt is over!\n");
fclose(in);
fclose(out);
sleep(1);
} if(ch0==2)
{
clrscr();
printf("\nPlease input the infile:");
scanf("%s",infile);/*输入需要解密的文件名*/ if((in=fopen(infile,"r"))==NULL)
{
printf("Can not open the infile!\n");
printf("Press any key to exit!\n");
getch();
exit(0);
} printf("Please input the key:");
scanf("%d",n);/*输入解密密码(可以为加密时候的密码)*/ n=26-n; printf("Please input the outfile:");
scanf("%s",outfile);/*输入解密后文件的文件名*/ if((out=fopen(outfile,"w"))==NULL)
{
printf("Can not open the outfile!\n");
printf("Press any key to exit!\n");
fclose(in);
getch();
exit(0);
} while(!feof(in))
{
fputc(encrypt(fgetc(in),n),out);
}
printf("\nDecrypt is over!\n");
fclose(in);
fclose(out);
sleep(1);
} if(ch0==3)
{
clrscr();
printf("\nPlease input the infile:");
scanf("%s",infile);/*输入需要解密的文件名*/ if((in=fopen(infile,"r"))==NULL)
{
printf("Can not open the infile!\n");
printf("Press any key to exit!\n");
getch();
exit(0);
} printf("Please input the outfile:");
scanf("%s",outfile);/*输入解密后文件的文件名*/ if((out=fopen(outfile,"w"))==NULL)
{
printf("Can not open the outfile!\n");
printf("Press any key to exit!\n");
fclose(in);
getch();
exit(0);
} for(i=1;i=25;i++)/*暴力破解过程,在察看信息正确后,可以按Q或者q退出*/
{
rewind(in);
rewind(out);
clrscr();
printf("===============================================================================\n");
printf("The outfile is:\n");
printf("===============================================================================\n");
while(!feof(in))
{
ch1=encrypt(fgetc(in),26-i);
putch(ch1);
fputc(ch1,out);
}
printf("\n===============================================================================\n");
printf("The current key is: %d \n",i);/*显示当前破解所用密码*/
printf("Press Q to quit and other key to continue......\n");
printf("===============================================================================\n");
ch1=getch();
if(ch1==q||ch1==Q)/*按Q或者q时退出*/
{
clrscr();
logo();
printf("\nGood Bye!\n");
fclose(in);
fclose(out);
sleep(3);
exit(0);
}
} printf("\nForce decrypt is over!\n");
fclose(in);
fclose(out);
sleep(1);
}
menu();
ch0=getch();
}
clrscr();
logo();
printf("\nGood Bye!\n");
sleep(3);
}
#includeiostream
#includecstring
using namespace std;
//加密
void JiaMi(char plain[], char cipher[], char a[], int key)
{
int i;
for(i=0;istrlen(plain);i++)
{
int c,j;
c=int(plain[i]);
j=((c-65)+key)%26;
cipher[i]=a[j];
}
cipher[i]=0;
}
//解密
void JieMi(char cipher[], char plain[], char a[], int key)
{
int i;
for(i=0;istrlen(cipher);i++)
{
int c,j;
c=int(cipher[i]);
j=((c-65)-key+26)%26;
plain[i]=a[j];
}
plain[i]=0;
}
int main( )
{
cout"\n";
cout" ---------------凯撒加密算法-------------- "endlendl;
char a[26];
int i;
for(i=0;i26;i++)
{
a[i]=char(65+i);
}
cout"密码表为:"endl;
for( i=0;i26;i++)
{couti"------"a[i]'\t';
}
coutendl; //以上为密码表的定义;
char plain[64],cipher[64];
cout"\n***加密***\n"endl;
while(1)
{
cout"请输入明文(明文需用连续的大写字母):""\n";
cinplain;
for(i=0;istrlen(plain);i++)
{
if(plain[i]'A'||plain[i]'z')
break;}
if(i=strlen(plain)) break;
}
cout"您输入的明文为:"plainendl; //明文的输入;
int key;
cout"请输入您的密钥(必需是整数):";
cinkey;
cout"您输入的密钥为:"keyendl;
cout"所得的凯撒密码为:";
JiaMi(plain, cipher, a, key); //调用加密函数
coutcipher;
coutendl; cout"\n***解密***\n"endl;
cout"请输入您的凯撒密码(需用大写连续英文字母):";
cincipher;
cout"您输入的凯撒密码为:"cipherendl;
cout"请输入您的密钥(必需是整数):";
cinkey;
cout"您输入的密钥为:"keyendl;
cout"解密后的明文为:";
JieMi(cipher, plain, a, key); //调用解密函数
coutplain;
coutendl;
return 0;
}