操作系统课程设计报告加密与解密.doc
面向对象课程设计加密与解密学生姓名:;学 号:;班 级:计算机应用一班指导教师:; 2011-12-29 一··············实验目的二··············实验内容三·············实验算法及实验过程四··············源程序代码五··············实验总结一 实验目的1、复习、巩固C+语言的基础知识,进一步加深对C+语言的理解和掌握; 2、课程设计为学生提供了一个既动手又动脑,独立实践的机会,将课本上的理论知识和实际有机的结合起来,锻炼学生的分析解决实际问题的能力。提高学生适应实际,实践编程的能力;3、培养学生在项目开发中团队合作精神、创新意识及能力。二 实验内容 1、要求:(1).给定任意一个文本文件,进行加密,生成另一个文件。(2).对加密后的文件还原。(3).要求采用有多种加密算法,对多种加密算法进行比较。(4).采用图形用户界面。三 实验算法及实现过程 1、解密与解密算法算法:(1). 希腊数学家 欧几里得算法, 称为辗转相除,又叫“辗转相除法” 简单的描述就是,记gcd(a,b)表示非负整数a,b的最大公因数,那么:gcd(a,b) =gcd(b,a%b)。 (2). Euclid算法定义:gcd(a,b)=gcd(b, a+kb) a,b,k为任意整数 即gcd(a,b)=gcd(b, a mod b) a0,b>0Example:gcd(55,22)=gcd(22, 55mod22)=gcd(22,11)=11证明:假定d=gcd(a,b),那么有d|a和d|b.对任何正整数b,a 可表示为如下形式: a=kb+r r mod b, a mod b =r , 因 此,有(a mod b )= a-kb,k为某个整数。但由于d|b,b也 能整除kb, 而d|a,故有d|(a mod b), 这表明d 也是b 和(a mod b) 的公因子。由于这是可逆的,如果d 是b 和(a mod b) 的公因子,那么d|kb,且d|kb+(a mod b)这等同于 d|a。这样a和b的公因子集合等同于b 和(a mod b) 的公因子集合。 2、Euclid算法流程图四 源程序代码:#include<stdio.h> #include<string.h> #include <stdlib.h>#include <time.h> #include <math.h>#include <malloc.h>#define MAX 100#define LEN sizeof(struct slink) void sub(int aMAX,int bMAX ,int cMAX );struct slink int bignumMAX;/*bignum98用来标记正负号,1 正,0 负 bignum99来标记实际长度*/struct slink *next;/*/-建立的大数运算库-*/ void print( int aMAX ) int i; for(i=0;i<a99;i+) printf("%d",aa99-i-1);printf("nn");return; int cmp(int a1MAX,int a2MAX) int l1, l2; int i; l1=a199; l2=a299;if (l1>l2) return 1; if (l1<l2) return -1; for(i=(l1-1);i>=0;i-) if (a1i>a2i) return 1 ; if (a1i<a2i) return -1; return 0; void mov(int aMAX,int *b) int j; for(j=0;j<MAX;j+) bj=aj;return ; void mul(int a1MAX,int a2MAX,int *c) int i,j; int y; int x; int z; int w; int l1, l2; l1=a1MAX-1; l2=a2MAX-1;if (a1MAX-2='-'&& a2MAX-2='-') cMAX-2=0;else if (a1MAX-2='-') cMAX-2='-'else if (a2MAX-2='-') cMAX-2='-' for(i=0;i<l1;i+) for(j=0;j<l2;j+) x=a1i*a2j; y=x/10; z=x%10; w=i+j; cw=cw+z;cw+1=cw+1+y+cw/10;cw=cw%10; w=l1+l2;if(cw-1=0)w=w-1; cMAX-1=w; return; void add(int a1MAX,int a2MAX,int *c) int i,l1,l2; int len,tempMAX; int k=0; l1=a1MAX-1; l2=a2MAX-1;if(a1MAX-2='-')&&(a2MAX-2='-') cMAX-2='-'elseif (a1MAX-2='-') mov(a1,temp);tempMAX-2=0; sub(a2,temp,c); return;elseif (a2MAX-2='-')mov(a2,temp); temp98=0; sub(a1,temp,c); return;if(l1<l2) len=l1;else len=l2;for(i=0;i<len;i+) ci=(a1i+a2i+k)%10; k=(a1i+a2i+k)/10; if(l1>len) for(i=len;i<l1;i+) ci=(a1i+k)%10;k=(a1i+k)/10; if(k!=0) cl1=k; len=l1+1; else len=l1; elsefor(i=len;i<l2;i+)ci=(a2i+k)%10; k=(a2i+k)/10; if(k!=0) cl2=k; len=l2+1; else len=l2; c99=len; return; void sub(int a1MAX,int a2MAX,int *c) int i,l1,l2; int len,t1MAX,t2MAX; int k=0; l1=a1MAX-1; l2=a2MAX-1; if (a1MAX-2='-') && (a2MAX-2='-') mov(a1,t1); mov(a2,t2); t1MAX-2=0; t2MAX-2=0; sub(t2,t1,c);return; elseif( a2MAX-2='-')mov(a2,t2); t2MAX-2=0; add(a1,t2,c); return; else if (a1MAX-2='-')mov(a2,t2); t2MAX-2='-'add(a1,t2,c); return; if(cmp(a1,a2)=1) len=l2; for(i=0;i<len;i+) if (a1i-k-a2i)<0) ci=(a1i-a2i-k+10)%10; k=1; else ci=(a1i-a2i-k)%10; k=0; for(i=len;i<l1;i+) if (a1i-k)<0) ci=(a1i-k+10)%10; k=1; else ci=(a1i-k)%10;k=0; if(cl1-1=0)/*使得数组 C 中的前面所以 0 字符不显示了, 1000-20=0980->显示为 980 如 了*/ len=l1-1; i=2; while (cl1-i=0)/*111456-111450=00006,消除 0 后变成了 6;*/ len=l1-i; i+; else len=l1; elseif(cmp(a1,a2)=(-1) cMAX-2='-' len=l1; for(i=0;i<len;i+) if (a2i-k-a1i)<0) ci=(a2i-a1i-k+10)%10; k=1; else ci=(a2i-a1i-k)%10; k=0; for(i=len;i<l2;i+) if (a2i-k)<0) ci=(a2i-k+10)%10;k=1; else ci=(a2i-k)%10; k=0; if(cl2-1=0) len=l2-1; i=2; while (cl1-i=0) len=l1-i; i+; else len=l2; else if(cmp(a1,a2)=0) len=1; clen-1=0; cMAX-1=len; return; void mod(int aMAX,int bMAX,int *c)/*/c=a mod b/注意:经检验知道此处 A 和 C 的数 组都改变了.*/ int dMAX; mov (a,d); while (cmp(d,b)!=(-1)/*/c=a-b-b-b-b-b.until(c<b)*/ sub(d,b,c); mov(c,d);/*/c 复制给 a*/ return ;void divt(int tMAX,int bMAX,int *c ,int *w)/*/试商法/调用以后 w 为 a mod b, C 为 a div b;*/ int a1,b1,i,j,m;/*w 用于暂时保存数据*/ int dMAX,eMAX,fMAX,gMAX,aMAX;mov(t,a); for(i=0;i<MAX;i+) ei=0; for(i=0;i<MAX;i+) di=0;for(i=0;i<MAX;i+) gi=0; a1=aMAX-1; b1=bMAX-1;if (cmp(a,b)=(-1) c0=0;cMAX-1=1; mov(t,w); return; else if (cmp(a,b)=0) c0=1; cMAX-1=1;w0=0; wMAX-1=1; return; m=(a1-b1);for(i=m;i>=0;i-)/*341245/3=341245-300000*1->41245-30000*1->11245-3000*3->2245-30 0*7->145-30*4=25->25-3*8=1*/ for(j=0;j<MAX;j+) dj=0;di=1;dMAX-1=i+1;mov(b,g); mul(g,d,e);while (cmp(a,e)!=(-1)ci+;sub(a,e,f);mov(f,a);/*f 复制给 g*/ for(j=i;j<MAX;j+)/*高位清零*/ej=0; mov(a,w); if (cm=0)cMAX-1=m; else cMAX-1=m+1; return; void mulmod(int aMAX ,int bMAX ,int nMAX,int *m)/*解决 了 m=a*b mod n;*/ int cMAX,dMAX; int i; for(i=0;i<MAX;i+)di=ci=0;mul(a,b,c);divt(c,n, d,m); for(i=0;i<mMAX-1;i+) printf("%d",mmMAX-1-i-1);printf("nm length is : %d n",mMAX-1); /*接下来的重点任务是要着手解决 m=ap mod n 的函数问题.*/ void expmod(int aMAX ,int pMAX ,int nMAX,int *m)int tMAX,lMAX,tempMAX; /*/t 放入 2,l 放入 1;*/ int wMAX,sMAX,cMAX,bMAX,i;for(i=0;i<MAX-1;i+) bi=li=ti=wi=0;t0=2;tMAX-1=1; l0=1;lMAX-1=1;mov(l,temp);mov(a,m);mov(p,b); while(cmp(b,l)!=0) for(i=0;i<MAX;i+) wi=ci=0;divt(b,t,w,c);/*/ c=p mod 2 w=p/2*/mov(w,b);/*/p=p/2*/if(cmp(c,l)=0) /*/余数 c=1*/ for(i=0;i<MAX;i+) wi=0; mul(temp,m,w); mov(w,temp); for(i=0;i<MAX;i+) wi=ci=0;divt(temp,n,w,c);/* c 为余 c=temp % n,w 为商 w=temp/n */ mov(c,temp); for(i=0;i<MAX;i+) si=0; mul(m,m,s);/s=a*a for(i=0;i<MAX;i+) ci=0; divt(s,n,w,c);/*w=s/n;c=s mod n*/ mov (c,m); for(i=0;i<MAX;i+)si=0;/w= p /2mul(m,temp,s); for(i=0;i<MAX;i+) ci=0; divt(s,n,w,c);mov (c,m);/*余数 s 给 m*/ mMAX-2=aMAX-2;/*为后面的汉字显示需要,用第 99 位做为标记*/ return;/*/k=temp*k%n;*/ int is_prime_san(int pMAX)int i,aMAX,tMAX,sMAX,oMAX;for(i=0;i<MAX;i+) si=oi=ai=ti=0; t0=1; tMAX-1=1; a0=2;/ 2,3,5,7 aMAX-1=1;sub(p,t,s);expmod ( a, s, p ,o); if ( cmp(o,t) != 0 ) return 0; a0=3; for(i=0;i<MAX;i+) oi=0;expmod ( a, s, p ,o);if ( cmp(o,t) != 0 ) return 0;a0=5;for(i=0;i<MAX;i+) oi=0; expmod ( a, s, p ,o); if ( cmp(o,t) != 0 ) return 0; a0=7; for(i=0;i<MAX;i+) oi=0;expmod ( a, s, p ,o); if ( cmp(o,t) != 0 ) return 0; return 1; int coprime(int eMAX,int sMAX) /*/ 求两个大数之间是否互质/*/ int aMAX,bMAX,cMAX,dMAX,oMAX,lMAX; int i; for(i=0;i<MAX;i+)li=oi=ci=di=0; o0=0;oMAX-1=1; l0=1; lMAX-1=1; mov(e,b); mov(s,a);do if(cmp(b,l)=0) return 1; for(i=0;i<MAX;i+)ci=0; divt(a,b,d,c);mov(b,a);/*b->a*/ mov(c,b);/*c->b*/while(cmp(c,o)!=0);/* printf("Ihey are not coprime!n");*/return 0; void prime_random(int *p,int *q) int i,k; time_t t;p0=1; q0=3; / p19=1;/ q18=2; pMAX-1=10;qMAX-1=11;do t=time(NULL); srand(unsigned long)t);for(i=1;i<pMAX-1-1;i+) k=rand()%10; pi=k; k=rand()%10;while (k=0) k=rand()%10; ppMAX-1-1=k;while(is_prime_san(p)!=1); printf("素数 p 为 : ");for(i=0;i<pMAX-1;i+) printf("%d",ppMAX-1-i-1); printf("nn"); do t=time(NULL); srand(unsigned long)t);for(i=1;i<qMAX-1;i+) k=rand()%10;qi=k; while(is_prime_san(q)!=1); printf("素数 q 为 : "); for(i=0;i<qMAX-1;i+) printf("%d",qqMAX-1-i-1); printf("nn"); return; void erand(int eMAX,int mMAX) int i,k;time_t t; eMAX-1=5;printf("随机产生一个与(p-1)*(q-1)互素的 e :");do t=time(NULL); srand(unsigned long)t);for(i=0;i<eMAX-1-1;i+) k=rand()%10; ei=k; while(k=rand()%10)=0)k=rand()%10; eeMAX-1-1=k; while(coprime( e, m)!=1);for(i=0;i<eMAX-1;i+)printf("%d",eeMAX-1-i-1); printf("nn");return ; void rsad(int eMAX,int gMAX,int *d) int rMAX,n1MAX,n2MAX,kMAX,wMAX; int i,tMAX,b1MAX,b2MAX,tempMAX; mov(g,n1); mov(e,n2);for(i=0;i<MAX;i+)ki=wi=ri=tempi=b1i=b2i=ti=0;b1MAX-1=0;b10=0;/*/b1=0;*/ b2MAX-1=1;b20=1;/*/b2=1;*/ while(1) for(i=0;i<MAX;i+) ki=wi=0; divt(n1,n2,k,w);/*/k=n1/n2;*/ for(i=0;i<MAX;i+) tempi=0; mul(k,n2,temp);/*/temp=k*n2;*/for(i=0;i<MAX;i+) ri=0; sub(n1,temp,r); if(rMAX-1=1) && (r0=0)/*/r=0*/ break;else mov(n2,n1);/*/n1=n2;*/ mov( r,n2);/*/n2=r;*/ mov(b2, t);/*/t=b2;*/ for(i=0;i<MAX;i+) tempi=0; mul(k,b2,temp);/*/b2=b1-k*b2;*/ for(i=0;i<MAX;i+) b2i=0;sub(b1,temp,b2); mov(t,b1); for(i=0;i<MAX;i+) ti=0; add(b2,g,t);for(i=0;i<MAX;i+)tempi=di=0; divt(t,g,temp,d); printf("由以上的(p-1)*(q-1)和 e 计算得出的 d : ");for(i=0;i<dMAX-1;i+)printf("%d",ddMAX-1-i-1);printf("nn"); /*/求解密密钥 d 的函数(根据 Euclid 算法)96403770511368768000*/ unsigned long rsa(unsigned long p,unsigned long q,unsigned long e)/*/求解密密钥 d 的函数 (根据 Euclid 算法)*/ unsigned long g,k,r,n1,n2,t;unsigned long b1=0,b2=1; g=(p-1)*(q-1);n1=g; n2=e; while(1)k=n1/n2; r=n1-k*n2;if(r!=0) n1=n2; n2=r; t=b2; b2=b1-k*b2; b1=t; else break; return (g+b2)%g; /*/-导入导出公钥和私钥-/*/ void loadpkey(int eMAX,int nMAX)/导入公钥FILE *fp; char filename25,strMAX,ch;int i,k;for(i=0;i<MAX;i+)ei=ni=0; while(1) printf("n");printf("为导入(e,n),请输入加密密钥对文件的绝对路径: n"); scanf("%s",filename); if(fp=fopen(filename,"r")=NULL) printf("输入的文件不存在,请重新输入!n"); else break; k=0; while(ch=fgetc(fp)!=EOF) if(ch!=' ') strk=ch;k+; else for(i=0;i<k;i+)ei=strk-i-1-48; eMAX-1=k; k=0; for(i=0;i<k;i+) ni=strk-i-1-48;nMAX-1=k; printf("n 加密密钥 e : "); for(i=0;i<eMAX-1;i+) printf("%d",eeMAX-1-i-1); printf("n");printf("n 公钥 n : "); for(i=0;i<nMAX-1;i+)printf("%d",nnMAX-1-i-1);printf("n"); fclose(fp); printf("n 导入(e,n)成功!n"); getchar(); void loadskey(int dMAX,int nMAX) /导入私钥 FILE *fp; char filename25,strMAX,ch; int i,k; for(i=0;i<MAX;i+)di=ni=0; while(1) printf("为导入(d,n),请输入解密密钥对文件的绝对路径: n"); scanf("%s",filename); if(fp=fopen(filename,"r")=NULL) printf("输入的文件不存在,请重新输入!n"); else break; k=0; while(ch=fgetc(fp)!=EOF) if(ch!=' ') strk=ch; k+; else for(i=0;i<k;i+)di=strk-i-1-48; dMAX-1=k; k=0; for(i=0;i<k;i+)ni=strk-i-1-48; nMAX-1=k; printf("n 解密密钥 d : ");for(i=0;i<dMAX-1;i+)printf("%d",ddMAX-1-i-1);printf("n");printf("n 公钥 n : "); for(i=0;i<nMAX-1;i+)printf("%d",nnMAX-1-i-1);printf("n"); fclose(fp); printf("n 导入(d,n)成功!n"); getchar(); void savepkey(int eMAX,int nMAX)/导出公钥 FILE *fp; int i;char savefile25,ch;printf("导出加密密钥(e,n),存放文件的绝对路径为: "); scanf("%s",savefile); printf("n"); fp=fopen(savefile,"w"); for(i=0;i<eMAX-1;i+) ch=eeMAX-1-i-1+48; fputc(ch,fp); ch=' 'fputc(ch,fp);for(i=0;i<nMAX-1;i+)ch=nnMAX-1-i-1+48;fputc(ch,fp); fclose(fp);printf("n 保存(e,n)操作完成!n"); void saveskey(int dMAX,int nMAX)/导出私钥 FILE *fp; int i; char savefile25,ch; printf("导出解密密钥(d,n),存放的文件的绝对路径为: "); scanf("%s",savefile); printf("n");fp=fopen(savefile,"w"); for(i=0;i<dMAX-1;i+) ch=ddMAX-1-i-1+48; fputc(ch,fp); ch=' 'fputc(ch,fp);for(i=0;i<nMAX-1;i+) ch=nnMAX-1-i-1+48; fputc(ch,fp); fclose(fp);printf("n 保存(d,n)操作完成!n");/*/-加密和解密的块-/*/ void printbig(struct slink *h)struct slink *p; int i;p=(struct slink * )malloc(LEN);p=h; if(h!=NULL)do for(i=0;i<p->bignumMAX-1;i+)printf("%d",p->bignump->bignumMAX-1-i-1);p=p->next; while(p!=NULL);printf("nn"); void tencrypto(int eMAX, int nMAX)/* 对有需要的文件进行加密*/ FILE *fp;int i,k,count,temp,c;char filename25,ch,encryfile25;struct slink *p,*p1,*p2;struct slink *h;h=p=p1=p2=(struct slink * )malloc(LEN);h=NULL;printf("n 输入需要加密的文件的绝对路径 : "); scanf("%s",filename); if(fp=fopen(filename,"r")=NULL)printf("Cannot open file !n");exit(0); printf("n 文件的原文内容:nn");count=0;while(ch=fgetc(fp)!=EOF) putchar(ch); c=ch;