效果很不稳定,快开学了,没时间弄了。因为学校宿舍不给电啊``~~ /************************************************************************ * * 文件名:《暗算解密 v0.01》 * * 文件描述:解密软件 * * 创建人: 柳 晛, 2007年3月7日 * * 版本号:0.01 * * 修改记录:尚未修改记录 * ************************************************************************/ #include "stdio.h" #include "string.h" #include "stdlib.h" void main() { /* 数组KEY存储用户输入的密钥,数组date存储待解密数据 */ char KEY[4][512]={0}, temp, date[4004][256]={0}; /* 数组key存储矩阵密钥,数组h存储密钥长度,i、j、x、y、ki都是计数器,fi记录密文串长度 */ int key[3][256]={0}, h[3], i, j, x, y, ki=0, fi=0; /* 文件指针fp1指向明文文件,fp2、fp3指向临时文件,fp4指向密文文件 */ FILE *fp1, *fp2, *fp3, *fp4; printf("/************************************************************************/n*/n* 文件名:《暗算解密 v0.01》/n*/n* 文件描述:解密软件/n*/n* 创建人: 柳 晛, 2007年3月7日/n*/n* 版本号:0.01/n*/n* QQ:252620084/tE-mail:Hack95@Gmail.com/n*/n* http://hi.baidu.com/hack95/n*/n************************************************************************//n"); if((fp4=fopen("读论语有感.txt","r"))==NULL) { printf("Error:“读论语有感.txt”文件无法打开!/n/n请将密文文件重命名为“读论语有感.txt”并放在本软件同一目录中。/n/n按Enter键退出该软件。"); getchar(); exit(0); } if((fp3=fopen("TEMP2.dat","w+"))==NULL) { printf("Error:临时存储文件TEMP2.dat无法建立!/n/n如果该文件无法正常建立,将不能执行解密运算。/n/n按Enter键退出该软件。"); getchar(); exit(0); } if((fp2=fopen("TEMP1.dat","w+"))==NULL) { printf("Error:临时存储文件TEMP1.dat无法建立!/n/n如果该文件无法正常建立,将不能执行解密运算。/n/n按Enter键退出该软件。"); getchar(); exit(0); } if((fp1=fopen("a.txt","w+"))==NULL) { printf("Error:明文文件a.txt无法建立/n/n明文数据无法存盘/n/n按Enter键退出该软件。"); getchar(); exit(0); } /* 以下3行代码测量待解密字符串的长度 */ fseek(fp4,0,SEEK_END); fi=ftell(fp4); printf("密文文件“读论语有感.txt”共%d字节/n/n",fi); /* 以下4行代码将待解密串传送到TEMP2.bat文件中 */ fseek(fp4,0,SEEK_SET); fseek(fp3,0,SEEK_SET); for(i=0;i<fi;i++) fputc(fgetc(fp4),fp3); fclose(fp4); /* ★ 74~116行代码用来处理用户输入的密钥 ★ */ while(ki<3) { printf("/n请输入第%d把密钥:",ki+1); gets(KEY[ki]); h[ki]=strlen(KEY[ki]); /* 以下10行代码过滤用户重复输入的密钥字符 */ for(i=0;i<h[ki];i++) for(j=i+1;j<h[ki];) if(KEY[ki][i]==KEY[ki][j]) { h[ki]--; for(x=j;x<=h[ki];x++) KEY[ki][x]=KEY[ki][x+1]; } else j++; /* 以下9行代码对用户输入的密钥进行由小到大排序 */ strcpy(KEY[3],KEY[ki]);/* 排序前备份过滤好的KEY */ for(i=0;i<h[ki];i++) for(j=i+1;j<h[ki];j++) if(KEY[ki][i]>KEY[ki][j]) { temp=KEY[ki][i]; KEY[ki][i]=KEY[ki][j]; KEY[ki][j]=temp; } /* 以下4行代码判断出数字矩阵的密钥并存入key */ for(i=0;i<h[ki];i++) for(j=0;j<h[ki];j++) if(KEY[ki][i]==KEY[3][j]) key[ki][j]=i; /* for(i=0;i<h[ki];i++) printf("%d,",key[ki][i]); printf("/n"); 这3行代码验证前方密钥处理过程是否正确*/ ki++;/* 一把密钥处理完毕,ki累加进入下一把密钥的处理过程 */ } /* ★ 122~157行代码利用key 对数据进行按位异或解密 ★ */ /* 以下24行代码将密钥串连起来,与待解密数据长度相同,准备逐一异或运算 */ fseek(fp1,0,SEEK_SET); i=0; j=0; for(x=0;x<fi;x++) { if(KEY[i][j]>0) { fputc(KEY[i][j],fp1); j++; } else { i++; j=0; if(KEY[i][j]>1) { fputc(KEY[i][j],fp1); j++; } else { i=0; fputc(KEY[i][j],fp1); j++; } } } /* 以下8行代码用来进行异或运算并存储在TEMP1.dat */ fseek(fp3,0,SEEK_SET); fseek(fp2,0,SEEK_SET); fseek(fp1,0,SEEK_SET); for(i=0;i<fi;i++) { temp=fgetc(fp1)^fgetc(fp3); fputc(temp,fp2); } /* ★ 165~194行代码利用key 对数据进行变位解密 ★ */ for(ki=0;ki<3;ki++)/* 该循环控制循环体内部依次使用第1、第2、第3把密钥 */ { for(x=0;x<h[ki];x++)/* 该循环使每把密钥对数据解密多次,次数等于密钥的长度 */ { /* 以下11行代码实现将TEMP1.dat存放的密文按照key存读入date数组中 */ fseek(fp2,0,SEEK_SET); for(i=0;i<h[ki];i++) { y=key[ki][i];/* 将当前key第i个密钥的值存入y,y控制调用date数组的第几列 */ for(j=0;j<(int)fi/h[ki];j++)/* 循环将date按照key规定的顺序纵向读取 */ { date[j][y]=fgetc(fp2); if(y<fi%h[ki]) date[++j][y]=fgetc(fp2); } } /* 以下4行代码实现将排到date中的密文按照解密顺序写入TEMP1.dat文件 */ fseek(fp2,0,SEEK_SET); for(i=0;date[i][j];i++) for(j=0;j<h[ki];j++) fputc(date[i][j],fp2); } } /* 以下4行代码实现解密后文件的存盘操作 */ fseek(fp2,0,SEEK_SET); fseek(fp1,0,SEEK_SET); for(i=0;i<fi;i++) fputc(fgetc(fp2),fp1); /* ★ 201~211行代码将临时文件TEMP1.dat、TEMP2.dat销毁 ★ */ fseek(fp2,0,SEEK_SET); fseek(fp3,0,SEEK_SET); for(i=0;i<fi;i++) { fputc('*',fp2); fputc('*',fp3); } fclose(fp2); fclose(fp3); unlink("TEMP1.dat"); unlink("TEMP2.dat"); }