效果很不稳定,快开学了,没时间弄了。因为学校宿舍不给电啊``~~ /************************************************************************ * * 文件名:《暗算加密 v0.01》 * * 文件描述:加密软件 * * 创建人: 柳 晛, 2007年3月7日 * * 版本号:0.01 * * 修改记录:尚未修改记录 * ************************************************************************/ #include "stdio.h" #include "string.h" #include "stdlib.h" void main() { /* 数组KEY[0~2]存储用户输入的密钥,数组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((fp1=fopen("a.txt","r"))==NULL) { printf("Error:a.txt文件找不到或无法打开!/n/n请将明文文件重命名为a.txt并放在本软件同一目录中。/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((fp3=fopen("TEMP2.dat","w+"))==NULL) { printf("Error:临时存储文件TEMP2.dat无法建立!/n/n如果该文件无法正常建立,将不能执行加密运算。/n/n按Enter键退出该软件。"); getchar(); exit(0); } if((fp4=fopen("读论语有感.txt","w+"))==NULL) { printf("Error:读论语有感.txt文件无法建立!该文件存储加密之后的数据。/n/n按Enter键退出该软件。"); getchar(); exit(0); } /* 以下3行代码测量明文字符串的长度 */ fseek(fp1,0,SEEK_END); fi=ftell(fp1); printf("明文文件a.txt共%d字节/n/n任何一把密钥的非重复字符数不得少于%d个/n",fi,fi/4000+2); /* 以下4行代码将明文串传送到TEMP1.bat文件中 */ fseek(fp1,0,SEEK_SET); fseek(fp2,0,SEEK_SET); for(i=0;i<fi;i++) fputc(fgetc(fp1),fp2); fclose(fp1);/* 关闭fp1 */ /* ★ 75~124行代码用来处理用户输入的密钥 ★ */ while(ki<3) { printf("/n请输入第%d把密钥:",ki+1); gets(KEY[ki]); printf("请确认第%d把密钥:",ki+1); gets(KEY[3]); if(KEY[3][1]==0||KEY[3][0]==KEY[3][1]||strcmp(KEY[ki],KEY[3])!=0) printf("/nError:密钥设置过于简单or密钥确认错误,请重新输入第%d把密钥!/n/n提示:每把密钥至少需要两位非重复字符。/n如:aa、aaa则不可,ab、abc或更复杂的密钥才认为是合法密钥。/n",ki+1); else { 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累加进入下一把密钥的处理过程 */ } } /* ★ 132~158行代码利用key 对数据进行变位加密 ★ */ for(ki=0;ki<3;ki++)/* 该循环控制循环体内部依次使用第1、第2、第3把密钥 */ { for(x=0;x<h[ki];x++)/* 该循环使每把密钥对数据加密多次,次数等于密钥的长度 */ { /*以下4行代码将明文串按照密钥规定的矩阵传送至数组date中*/ fseek(fp2,0,SEEK_SET); for(i=0;!feof(fp2);i++) for(j=0;j<h[ki];j++)/* 用当前key的长度h[ki]来限制横向填充到date数组中的串 */ date[i][j]=fgetc(fp2); /* for(i=0;i<10;i++) { for(j=0;j<10;j++) printf("%c",date[i][j]); printf("/n"); }这六行代码验证前方date数组是否填充正确*/ /* 以下6行代码实现向TEMP1.dat临时文件中存放加密过程中的数据 */ fseek(fp2,0,SEEK_SET); for(i=0;i<h[ki];i++) { y=key[ki][i];/* 将当前key第i个密钥的值存入y */ for(j=0;date[j][y]>0;j++)/* 循环将date按照key规定的顺序纵向存储 */ fputc(date[j][y],fp2); } } } /* ★ 165~201行代码利用key 对数据进行按位异或加密 ★ */ /* 以下24行代码将密钥串连起来,与明文数据长度相同,准备逐一异或运算 */ fseek(fp3,0,SEEK_SET); i=0; j=0; for(x=0;x<fi;x++) { if(KEY[i][j]>0) { fputc(KEY[i][j],fp3); j++; } else { i++; j=0; if(KEY[i][j]>0) { fputc(KEY[i][j],fp3); j++; } else { i=0; fputc(KEY[i][j],fp3); j++; } } } /* 以下8行代码用来进行异或运算并将最终结果存盘 */ fseek(fp2,0,SEEK_SET); fseek(fp3,0,SEEK_SET); fseek(fp4,0,SEEK_SET); for(i=0;i<fi;i++) { temp=fgetc(fp2)^fgetc(fp3); fputc(temp,fp4); } fclose(fp4); /* ★ 208~218行代码将临时文件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"); }