www.pudn.com > des数据加密算法原理与实现..zip > Des.c


/********************************************************************/ 
/*DES加密程序			1998.3.11									*/ 
/*使用方法:															*/ 
/*		加密:		DES FILENAME								*/ 
/*					TYPE PASSWORD FOR FILENAME  XXXXXXXX 8字节		*/ 
/*		解密:		DES FILENAME								*/ 
/*					TYPE PASSWORD FOR FILENAME  XXXXXXXX 8字节		*/ 
/*在vc++1.5或tc2.0 DOS6.22下调试通过								*/ 
/********************************************************************/ 
/*置换算法: 
	为完成char inblock[8]按换位表charip[64]变换到char outblock[8],先生 
	成一个变换矩阵 char perm[i][j][k],i=16,j=16,k=8 
	i:把输入的64bit分成四位一组,每次处理四位信息 
	j:四位可表示0......15,共16个值 
	k:对应j的每一个值,给出一个8字节的矩阵表示对应的位的值为1 
	比如: 
	char inblock{11111110b, 
				 01011101b, 
				 01011010b, 
				 00010100b, 
				 10101011b, 
				 11111000b, 
				 00000100b, 
				 10000101b} 
	则: 
		char *perm[0][15]={00000001b, 
						   00000001b, 
						   00000000b, 
						   00000000b, 
						   00000001b, 
						   00000001b, 
						   00000000b, 
						   00000000b} 
 
		char *perm[1][14]={00000000b, 
						   00000000b, 
						   00000001b, 
						   00000000b, 
						   00000000b, 
						   00000000b, 
						   00000001b, 
						   00000001b} 
 
	   char *perm[15][15]={00000000b, 
						   00000000b, 
						   10000000b, 
						   10000000b, 
						   00000000b, 
						   00000000b, 
						   10000000b, 
						   10000000b} 
		char *ip[] 
		={	58, 50, 42, 34, 26, 18, 10,  2, 
		    60, 52, 44, 36, 28, 20, 12,  4, 
			62, 54, 46, 38, 30, 22, 14,  6, 
			64, 56, 48, 40, 32, 24, 16,  8, 
			57, 49, 41, 33, 25, 17,  9,  1, 
			59, 51, 43, 35, 27, 19, 11,  3, 
			61, 53, 45, 37, 29, 21, 13,  5, 
			63, 55, 47, 39, 31, 23, 15,  7	}; 
*/ 
 
/*#define DEBUG 	*/ 
 
#include  
 
char iperm[16][16][8],fperm[16][16][8]; 
char s[4][4096]; 
char p32[4][256][4]; 
char kn[16][6];				/* 密钥*/ 
 
endes(inblock,outblock)			/* 加密一个64-bit块*/ 
char *inblock, *outblock; 
{	char iters[17][8]; 
	char swap[8];			/* 放置左右交换的值*/ 
	register int i; 
	register char *s, *t; 
 
	permute(inblock,iperm,iters[0]); 
	for (i=0; i<16; i++)			/* 完成1~16层的交换*/ 
		iter(i,iters[i],iters[i+1]); 
						/* iters[0][0]~iters[0][8]操作后放到iters[1][0]~iters[1][8] 
					iters[1][0]~iters[1][8]操作后放到iters[2][0]~iters[2][8]...以此类推*/ 
	s = swap; t = &iters[16][4]; 
	*s++ = *t++; *s++ = *t++; *s++ = *t++; *s++ = *t++; 
	t = &iters[16][0]; 
	*s++ = *t++; *s++ = *t++; *s++ = *t++; *s++ = *t++; 
	permute(swap,fperm,outblock); 
} 
 
dedes(inblock,outblock)			/* 解密一个64-bit 块*/ 
char *inblock,*outblock; 
{	char iters[17][8]; 
	char swap[8]; 
	register int i; 
	register char *s, *t; 
 
	permute(inblock,iperm,iters[0]); 
	for (i=0; i<16; i++) 
		iter(15-i,iters[i],iters[i+1]); 
 
	s = swap; t = &iters[16][4]; 
	*s++ = *t++; *s++ = *t++; *s++ = *t++; *s++ = *t++; 
	t = &iters[16][0]; 
	*s++ = *t++; *s++ = *t++; *s++ = *t++; *s++ = *t++; 
	permute(swap,fperm,outblock); 
} 
 
permute(inblock,perm,outblock)		/* 初始换位/最后换位变换*/ 
char *inblock, *outblock; 
char perm[16][16][8]; 
{	register int i,j; 
	register char *ib, *ob; 
	register char *p, *q; 
 
	for (i=0, ob = outblock; i<8; i++) 
		*ob++ = 0; 
	ib = inblock; 
	for (j = 0; j < 16; j += 2, ib++) 
	{	ob = outblock; 
		p = perm[j][(*ib >> 4) & 017];	/*高四位*/ 
		q = perm[j + 1][*ib & 017];		/*低四位*/ 
		for (i = 0; i < 8; i++) 
			*ob++ |= *p++ | *q++; 
		/*-----------------*(ob++)=(*ob)|(*(p++)|*(q++))-----------------*/ 
	} 
} 
 
char ip[]				/* 初始换位表*/ 
= {	58, 50, 42, 34, 26, 18, 10,  2, 
	60, 52, 44, 36, 28, 20, 12,  4, 
	62, 54, 46, 38, 30, 22, 14,  6, 
	64, 56, 48, 40, 32, 24, 16,  8, 
	57, 49, 41, 33, 25, 17,  9,  1, 
	59, 51, 43, 35, 27, 19, 11,  3, 
	61, 53, 45, 37, 29, 21, 13,  5, 
	63, 55, 47, 39, 31, 23, 15,  7	}; 
 
char fp[]			/* 最后换位表*/ 
= {	40,  8, 48, 16, 56, 24, 64, 32, 
	39,  7, 47, 15, 55, 23, 63, 31, 
	38,  6, 46, 14, 54, 22, 62, 30, 
	37,  5, 45, 13, 53, 21, 61, 29, 
	36,  4, 44, 12, 52, 20, 60, 28, 
	35,  3, 43, 11, 51, 19, 59, 27, 
	34,  2, 42, 10, 50, 18, 58, 26, 
	33,  1, 41,  9, 49, 17, 57, 25	}; 
 
char pc1[]				/* pc1表*/ 
= {	57, 49, 41, 33, 25, 17,  9, 
	 1, 58, 50, 42, 34, 26, 18, 
	10,  2, 59, 51, 43, 35, 27, 
	19, 11,  3, 60, 52, 44, 36, 
 
	63, 55, 47, 39, 31, 23, 15, 
	 7, 62, 54, 46, 38, 30, 22, 
	14,  6, 61, 53, 45, 37, 29, 
	21, 13,  5, 28, 20, 12,  4	}; 
 
char totrot[]			   /* 密钥生成中的循环左移位的累计次数*/ 
= {	1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28	}; 
 
char pc1m[56]; 
char pcr[56]; 
 
char pc2[]				/* pc2表*/ 
= {	14, 17, 11, 24,  1,  5, 
	 3, 28, 15,  6, 21, 10, 
	23, 19, 12,  4, 26,  8, 
	16,  7, 27, 20, 13,  2, 
	41, 52, 31, 37, 47, 55, 
	30, 40, 51, 45, 33, 48, 
	44, 49, 39, 56, 34, 53, 
	46, 42, 50, 36, 29, 32	}; 
 
char si[8][64]			  /* 48->32 bit 压缩表*/ 
= {					/* S[1]			 */ 
	14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7, 
	 0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8, 
	 4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0, 
	15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13, 
					/* S[2]			 */ 
	15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10, 
	 3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5, 
	 0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15, 
	13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9, 
					/* S[3]			 */ 
	10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8, 
	13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1, 
	13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7, 
	 1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12, 
					/* S[4]			 */ 
	 7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15, 
	13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9, 
	10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4, 
	 3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14, 
					/* S[5]			 */ 
	 2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9, 
	14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6, 
	 4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14, 
	11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3, 
					/* S[6]			 */ 
	12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11, 
	10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8, 
	 9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6, 
	 4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13, 
					/* S[7]			 */ 
	 4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1, 
	13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6, 
	 1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2, 
	 6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12, 
					/* S[8]			 */ 
	13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7, 
	 1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2, 
	 7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8, 
	 2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11	}; 
 
char p32i[]				/* 32-bit 单纯换位表*/ 
= {	16,  7, 20, 21, 
	29, 12, 28, 17, 
	 1, 15, 23, 26, 
	 5, 18, 31, 10, 
	 2,  8, 24, 14, 
	32, 27,  3,  9, 
	19, 13, 30,  6, 
	22, 11,  4, 25	}; 
 
desinit(key)				/* 初始化各种变换矩阵*/ 
char *key; 
{ 
#ifdef DEBUG 
/*deb*/ printf("Initial perm init.\n"); 
#endif 
	perminit(iperm,ip); 
#ifdef DEBUG 
/*deb*/ printf("Final perm init.\n"); 
#endif 
	perminit(fperm,fp); 
#ifdef DEBUG 
/*deb*/ printf("Key sched init.\n"); 
#endif 
	kinit(key);	 
#ifdef DEBUG 
/*deb*/ printf("Compression init.\n"); 
#endif 
	sinit(); 
 
#ifdef DEBUG 
/*deb*/ printf("32-bit perm init.\n"); 
#endif 
	p32init(); 
#ifdef DEBUG 
/*deb*/ printf("End init.\n"); 
#endif 
} 
 
int bytebit[] 
	= {	0200,0100,040,020,010,04,02,01 }; 
 
int nibblebit[] = { 010,04,02,01 }; 
 
sinit()						 /* 初始化s1-s8矩阵*/ 
{	register int i,j; 
 
	for (i=0; i<4; i++)		/* 48位按四个12位(一个半字节)来输入*/ 
		for (j=0; j<4096; j++) 
			s[i][j]=(getcomp(i*2,j>>6)<<4) | 
				(017&getcomp(i*2+1,j&077));		/*每个s项为一个字节,存有两个体代数*/ 
} 
 
getcomp(k,v)				/* 用s[k]盒对v进行6bit~4bit的数据压缩*/ 
int k,v; 
{	register int i,j; 
 
	i=((v&040)>>4)|(v&1);			/*i为每个s盒的行号改行号由v的第一位和最后一位组成*/ 
	j=(v&037)>>1;					/* j位s盒的列号,该列号由v的中间四位组成*/ 
	return (int) si[k][(i<<4)+j];   /* 返回对v压缩后的值*/ 
} 
 
kinit(key)				/* 初始化密钥的变换矩阵的中间过渡矩阵*/ 
char *key;				/* 64 bits */ 
{	register int i,j,l; 
	int m; 
 
	for (j=0; j<56; j++) 
	{	l=pc1[j]-1;	 
		m = l & 07; 
		pc1m[j]=(key[l>>3] & bytebit[m]) ? 1 : 0; 
			/*key[l>>3]确定第1位在char key[8]中的哪一个字节中, 
						char pc1m[56]是完成pc-1型换位的变换矩阵*/ 
	} 
	for (i=0; i<16; i++)		/* 共生成16个密钥*/ 
		for (j=0; j<6; j++)		/* 密钥kn的每一个字节*/ 
			kn[i][j]=0;	 
	for (i=0; i<16; i++) 
	{	for (j=0; j<56; j++) 
		pcr[j] = pc1m[(l=j+totrot[i])<(j<28? 28 : 56) ? l: l-28]; 
								/* pcr[j]是每次进行循环左移位后的pc1m[]矩阵*/ 
		for (j=0; j<48; j++) 
		if (pcr[pc2[j]-1]) 
			{	l= j & 07; 
				kn[i][j>>3] |= bytebit[l];/*共16个密钥i~[0,16],每个密钥6字节j>>3~[0,5]*/ 
			} 
	} 
} 
 
p32init()				/* 初始化32bit换位表的中间过渡矩阵*/ 
{	register int l, j, k; 
	int i,m; 
 
	for (i=0; i<4; i++)			/* 以字节为单位输入,i为字节在输入矩阵中的位置*/ 
		for (j=0; j<256; j++)	/* j为所输入字节的可能值[0~256]*/ 
		for (k=0; k<4; k++) 
			p32[i][j][k]=0;	 
	for (i=0; i<4; i++) 
		for (j=0; j<256; j++) 
		for (k=0; k<32; k++) 
		{   l=p32i[k]-1; 
			if ((l>>3)!=i) 
			continue; 
			if (!(j&bytebit[l&07])) 
			continue; 
			m = k & 07; 
			p32[i][j][k>>3] |= bytebit[m]; 
		} 
} 
 
perminit(perm,p)				/* 初始化换位表*/ 
char perm[16][16][8];			/* 64-bit, 完成换位的中间的过渡矩阵*/ 
char p[64]; 
{	register int l, j, k; 
	int i,m; 
 
	for (i=0; i<16; i++)			/* 每一个输入的4 bit*/ 
		for (j=0; j<16; j++)		/* 每一个4 bit的可能值~[0,16]*/ 
		for (k=0; k<8; k++)			/* 每一个屏蔽字*/ 
			perm[i][j][k]=0;		/* 过渡矩阵清零*/ 
	for (i=0; i<16; i++)			/* 每一个输入的4 bit*/ 
		for (j = 0; j < 16; j++)	/* 每一个4 bit的可能值~[0,16]*/ 
		for (k = 0; k < 64; k++)	/* 每一个输出bit的位置*/ 
		{   l = p[k] - 1;			/* p[k]最小值为l,l从0开始*/ 
			if ((l >> 2) != i)		/* l~[0,63],每四位一组,共十六组,因此要l>>2*/ 
			continue;	 
			if (!(j & nibblebit[l & 3]))	/*确定第l~[0,63]位是一个四位组中的第几位*/ 
			continue; 
			m = k & 07;						/*确定第k~[0,63]位是一个字节中的第几位*/ 
			perm[i][j][k>>3] |= bytebit[m]; 
		} 
} 
 
iter(num,inblock,outblock)		/* 完成第num层的变换*/ 
int num; 
char *inblock, *outblock;			/* 64 bits	*/ 
{	char fret[4];					/* 放置f(R[i-1],key)的返回值*/ 
	register char *ib, *ob, *fb; 
 
 
	ob = outblock; 
	ib = &inblock[4];			/*右边32位*/ 
	f(ib, num, fret); 
	*ob++ = *ib++;				/* L[i] = R[i-1]		*/ 
	*ob++ = *ib++; 
	*ob++ = *ib++; 
	*ob++ = *ib++; 
	ib = inblock; fb = fret;	/* R[i]=L[i] XOR f(R[i-1],key)  */ 
	*ob++ = *ib++ ^ *fb++; 
	*ob++ = *ib++ ^ *fb++; 
	*ob++ = *ib++ ^ *fb++; 
	*ob++ = *ib++ ^ *fb++; 
} 
 
f(right,num,fret)			/* 完成num层的f()函数*/ 
char *right, *fret;			/* 32 bits */ 
int num; 
{	register char *kb, *rb, *bb; 
	char bigright[6]; 
	char result[6];	 
	char preout[4]; 
 
	kb = kn[num]; 
	bb = bigright; 
	rb = result; 
	expand(right,bb);			/*扩展成48bit*/ 
	*rb++ = *bb++ ^ *kb++; 
	*rb++ = *bb++ ^ *kb++;		/*Kn与Rn异或操作*/ 
	*rb++ = *bb++ ^ *kb++; 
	*rb++ = *bb++ ^ *kb++; 
	*rb++ = *bb++ ^ *kb++; 
	*rb++ = *bb++ ^ *kb++; 
	contract(result,preout);	/*用s盒得到32bit输出*/ 
	perm32(preout,fret);		/*最后换位*/ 
} 
 
perm32(inblock,outblock)		/* 单纯换位*/ 
char *inblock,*outblock;		/* of the f crypto function	*/ 
{	register int j; 
 
	register char *ib, *ob; 
	register char *q; 
 
	ob = outblock;				/* 把输出的块清零*/ 
	*ob++ = 0; *ob++ = 0; *ob++ = 0; *ob++ = 0; 
	ib=inblock;	 
	for (j=0; j<4; j++, ib++)	/* 输入的每一字节*/ 
	{	q = p32[j][*ib & 0377]; 
		ob = outblock;			/* 每一输出的字节*/ 
		*ob++ |= *q++;	 
		*ob++ |= *q++; 
		*ob++ |= *q++; 
		*ob++ |= *q++; 
	} 
} 
 
expand(right,bigright)			/* 用E变换矩阵完成32---48扩展换位*/ 
char *right,*bigright;			/* right 32 bit, bigright 48 bit	*/ 
{ 
	register char *bb, *r, r0, r1, r2, r3; 
 
	bb = bigright; 
	r = right; r0 = *r++; r1 = *r++; r2 = *r++; r3 = *r++; 
	*bb++ = ((r3 & 0001) << 7) |		/* 32				*/ 
		((r0 & 0370) >> 1) |			/* 1 2 3 4 5		*/ 
		((r0 & 0030) >> 3);				/* 4 5				*/ 
	*bb++ = ((r0 & 0007) << 5) |		/* 6 7 8			*/ 
		((r1 & 0200) >> 3) |			/* 9				*/ 
		((r0 & 0001) << 3) |			/* 8				*/ 
		((r1 & 0340) >> 5);				/* 9 10 11			*/ 
	*bb++ = ((r1 & 0030) << 3) |		/* 12 13			*/ 
		((r1 & 0037) << 1) |			/* 12 13 14 15 16	*/ 
		((r2 & 0200) >> 7);				/* 17				*/ 
	*bb++ = ((r1 & 0001) << 7) |		/* 16				*/ 
		((r2 & 0370) >> 1) |			/* 17 18 19 20 21	*/ 
		((r2 & 0030) >> 3);				/* 20 21			*/ 
	*bb++ = ((r2 & 0007) << 5) |		/* 22 23 24			*/ 
		((r3 & 0200) >> 3) |			/* 25				*/ 
		((r2 & 0001) << 3) |			/* 24				*/ 
		((r3 & 0340) >> 5);				/* 25 26 27			*/ 
	*bb++ = ((r3 & 0030) << 3) |		/* 28 29			*/ 
		((r3 & 0037) << 1) |			/* 28 29 30 31 32	*/ 
		((r0 & 0200) >> 7);				/* 1				*/ 
} 
 
contract(in48,out32)			/* 48位经s盒后,输出32位*/ 
char *in48,*out32; 
{	register char *c; 
	register char *i; 
	register int i0, i1, i2, i3, i4, i5; 
 
	i = in48; 
	i0 = *i++; i1 = *i++; i2 = *i++; i3 = *i++; i4 = *i++; i5 = *i++; 
	c = out32; 
	*c++ = s[0][07777 & ((i0 << 4) | ((i1 >> 4) & 017  ))]; 
	*c++ = s[1][07777 & ((i1 << 8) | ( i2	& 0377 ))]; 
	*c++ = s[2][07777 & ((i3 << 4) | ((i4 >> 4) & 017  ))]; 
	*c++ = s[3][07777 & ((i4 << 8) | ( i5	& 0377 ))]; 
} 
 
/************************ 以上是DES 的全部算法************************/ 
 
char *inname, *outname; 
FILE *infile, *outfile; 
 
int encrypting; 
char buf[512]; 
char keyx[9],keyy[9]; 
 
char *malloc(), *strcpy(), *strcat(); 
 
main(argc, argv) 
int argc; char *argv[]; 
{	register char *u; 
	char *filename; 
 
	if (argc < 2)						/* 命令行是否给出了文件名? */ 
	{  fprintf(stderr, "Usage: des file ...\n"); 
	   exit(1); 	 
	} 
 
	for (++argv; --argc; ++argv) 
	{	inname = *argv; 
		outname = filename = malloc((unsigned) strlen(inname) + 5); 
		strcpy(filename, inname); 
		u = &filename[strlen(filename) - 4];	/* 检查最后4个字符*/ 
 
		encrypting = (strcmp(".des", u) != 0); 
		if (!encrypting) *u = 0;			 /* 解密时输出文件去掉.des*/ 
		else strcat(filename, ".des");		 /* 加密时给输出文件加上.des*/ 
 
		if ((infile = fopen(inname, "rb")) == NULL) 
		{	fprintf(stderr,"Can't read %s.\n", inname); 
			exit(1); 
		} 
		if ((outfile = fopen(outname, "rb")) != NULL) 
		{	fprintf(stderr, "%s would be overwritten.\n",outname); 
			exit(1); 
		} 
		if ((outfile = fopen(outname, "wb")) == NULL) 
		{	fprintf(stderr,"Can't write %s.\n", outname); 
			exit(1); 
		} 
 
		key_get("Type password for "); 
		for (;;) 
		{	strcpy(keyx, keyy); 
			key_get("Verify password for "); 
			if (strcmp(keyx, keyy) == 0) break; 
		} 
		desinit(keyx);					 /*建立用于des运算的矩阵*/ 
 
		if (pfile() == 0) unlink(inname); 
		else	fprintf(stderr, 
			   "%s: I/O Error -- File unchanged\n", inname); 
 
		fclose(outfile); 
		fclose(infile); 
	} 
	exit(0); 
} 
 
key_get(mes)				/*输入密码*/ 
char *mes; 
{	register int i, j; 
	char linebuf[256]; 
	int count; 
 
				//	for (i=0; i<14; i++) keyy[i]=0; 
 
	printf("%s%s: ", mes, inname); 
	fflush(stdout);		/*使用read(),fread()前先刷新文件*/ 
 
	count = read(0, linebuf, 256);  /* 输入密码*/ 
	printf("\n"); 
 
 
	linebuf[count] = 0;  /* 添加一个0作为字符串的结束*/ 
	if (linebuf[count-1] == '\n') 
	{  linebuf[count-1] = 0;	/*把"\n"变成0*/ 
	   count--; 
	} 
	if (count > 8) count = 8;	/* 只取 8 字节 */ 
	for (i = j = 0; count--;) 
	   keyy[i++] = linebuf[j++]; 
} 
 
pfile()				 /* 文件加密处理*/ 
{	register int m, nsave; 
	register char *b; 
	int j; 
 
	while (m = fread(buf, 1, 512, infile)) 
	{ 
		if ((nsave = m) < 0)	/* 读出错*/ 
		return(-1); 
		for (b=buf; m>0;m -= 8, b += 8)		/* 加密解密一个缓冲区的块*/ 
		{   if (encrypting) 
		{   if (m<8)						/* 不够一块---64 bits	*/ 
			{   for (j=0; j<8-m; j++) 
				b[m+j]=garbage();			 /* 填充不够一块的部分*/ 
			nsave += 8-m;					/* 把nave凑成8的整数倍*/ 
			} 
			else j=0;						/* 不足8字节时的缺额数量j=8-m*/ 
			endes(b,b);	 
		} 
		else								/* 解密*/ 
		{   if (m < 8) deout(b, 1);			/* 最后的几个字节*/ 
			else 
			{   dedes(b, b);				/* 解密一个块*/ 
			deout(b, 0);					/*输出到文件*/ 
			} 
		} 
		} 
		if (encrypting) if (fwrite(buf, 1, nsave, outfile) != nsave) 
			return(-1); 
	} 
											/* 加密解密文件完成*/ 
	if (encrypting) fputc(8 - j, outfile);  /* 8-j=最后一个块的有效字节数*/ 
	return(0); 
} 
 
int outcount = 0; 
 
deout(block,flag)			/* 根据flag标志来决定输出到文件的内容*/ 
char *block,flag;			/* char*block 64-bit 块, flag=1:处理的块是文件的最后的块 
													  flag=0:处理的块不是文件的最后的块*/ 
{	static char last[8];		/*static char last[8] 前一个输入块,静态变量,初始化为零*/ 
	register int i; 
 
	if (flag)			/* 输出的最后的几个字节*/ 
	{ 
		fwrite(last, 1, block[0] & 0377, outfile); /*block[0]包含内容"8-j*/ 
		return; 
	} 
	if (outcount++)			/* 以前是否处理过块,即输入的加密文件长度不到8字节*/ 
		fwrite(last, 1, 8, outfile); 
	for (i = 0; i < 8; i++) last[i] = block[i]; /* 复制块*/ 
} 
 
garbage()				/* 产生一些数字用以填充不足8字节的块*/ 
/*产生数据随机性大一些,加密效果会更好*/ 
{ 
	return 0; 
} 
 
/*********************程序结束**************************/