⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dodes.cpp

📁 基于DES加密算法
💻 CPP
字号:
//File name:   doDes.cpp
// use DES algrithom to encryption or decryption a segment
//of memory

// interface:
//	setKey(char *k)-----Set the Key for DES
//	encryption(char *memory,DWORD length)
//  decryption(char *memory,DWORD length)
//==================================================================
//Public data for encryption and decryption
// two table for first selection and last selection

#include "doDes.h"

//#include "string.h"			// for strlen....


char ip[64]={	/* initial permutation P	*/
	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[64]={				/* final permutation F	  */
	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
};

// encryption a memory block
BOOL CDES::encryption (void *memory,DWORD pLength)
{	
	DWORD i,j;
	__int64 *pDat,iDat,leftPart,rightPart,temp;
	if(pLength%8){
		errorNumber=ERR_LENGTH;
		return  FALSE;
	}
	if(pTable==NULL){
		errorNumber=ERR_ALLOCATEMEMORY;
		return FALSE;
	}

	for(i=0,pDat=(__int64 *)memory
		;i<pLength;i+=8,pDat++){

		// first shuffle
		iDat=shuffle(*pDat,ip); 
		
		//divide to 2 partion
		leftPart =0xffffffff & iDat;		//  low  32bits
		rightPart=0xffffffff & (iDat>>32);	//  high 32 bits

		//do encryption function 16 times
		for(j=0;j<16;j++){
			temp=rightPart;
			
			rightPart=expand(rightPart);	//convert 32 to 48

			rightPart^=subKey[j];		//XOR
			rightPart=deflate(rightPart);	//convert 48 to 32 bits
			
			rightPart=shuffle32(rightPart);// shuffle 32 bits
			
			rightPart^=leftPart;
			leftPart=temp;
		}

		//combination
		iDat=(leftPart<<32) | rightPart;

		//last shuffle
		*pDat=shuffle(iDat,fp);
	}
	return TRUE;	//	finished successfully
}

BOOL CDES::decryption(void *memory,DWORD pLength)
{	DWORD i,j;
	__int64 *pDat,iDat,leftPart,rightPart,temp;
	if(pLength%8){
		errorNumber=ERR_LENGTH;
		return  FALSE;
	}
	if(pTable==NULL){
		errorNumber=ERR_ALLOCATEMEMORY;
		return FALSE;
	}

	for(i=0,pDat=(__int64 *)memory
		;i<pLength;i+=8,pDat++){

		// first shuffle
		iDat=shuffle(*pDat,ip); 
		
		//divide to 2 partion
		leftPart =0xffffffff & iDat;		//  low  32bits
		rightPart=0xffffffff & (iDat>>32);	//  high 32 bits

		//do encryption function 16 times
		for(j=0;j<16;j++){
			temp=rightPart;
			
			rightPart=expand(rightPart);	//convert 32 to 48

			rightPart^=subKey[15-j];		//XOR
			rightPart=deflate(rightPart);	//convert 48 to 32 bits
			
			rightPart=shuffle32(rightPart);// shuffle 32 bits
			
			rightPart^=leftPart;
			leftPart=temp;
		}

		//combination
		iDat=(leftPart<<32) | rightPart;

		//last shuffle
		*pDat=shuffle(iDat,fp);
	}
	return TRUE;	//	finished successfully
}



__int64 CDES::expand(__int64 x)
{
	char exp[48]={
		32, 1, 2, 3, 4, 5, 4, 5,
		 6, 7, 8, 9, 8, 9,10,11,
		12,13,12,13,14,15,16,17,
		16,17,18,19,20,21,20,21,
		22,23,24,25,24,25,26,27,
		28,29,28,29,30,31,32, 1
	};

	__int64 r;
	int i;
	
	for(i=0,r=0;i<48;i++){
		if(x & bitTable[exp[i]-1])
			r|=bitTable[i];
	}

	//r= x & bitTable[31]  ? 1:0;				//32	=>0
	/*
	r|=(x<<      1)& (__int64)0x3e;			//1,2,3,4,5
	r|=(x<<( 7- 4))& (__int64)0xfc0;		//4,5,6,..9
	r|=(x<<(13- 8))& (__int64)0x3f000;		//8,9...13
	r|=(x<<(19-12))& (__int64)0xfc0000;		//12,13,..17
	r|=(x<<(25-16))& (__int64)0x3f000000;	//,16,17,.21
	r|=(x<<(31-20))& (__int64)0xfc0000000;	//20,21,..25
	r|=(x<<(37-24))& (__int64)0x3f000000000;//24,25..29
	r|=(x<<(42-28))& (__int64)0xfc0000000000;//28,29...32
	if(x&0x1)
		r|=bitTable[47];			// bit 1=> 48
  */

	//r|=(x<<      1)& (__int64)0x3e;			//1,2,3,4,5
	//r|=x           & (__int64)3;			//4,5
	//r|=
	return r;
}

//convert 48bits to 32bits
//
__int64 CDES::deflate(__int64 x)
{
	__int64 r;		//return value
	char s12,s34,s56,s78;

	/*s12=*(pTable +(int)(x&0xfff));				//S1 and S2
	s34=*(pTable+ 4*1024+(int)((x>>12)&0xfff));	// S3,S4
	s56=*(pTable+ 8*1024+(int)((x>>24)&0xfff));	// S5,S6
	s78=*(pTable+12*1024+(int)((x>>36)&0xfff));	// S7,S8
*/

	s12=*(pTable +(int)(((x&0xff)<<4)|((x&0xf000)>>12)));	//S1 and S2
	s34=*(pTable+ 4*1024+
		(int)((x&0xf00)| (x>>16)&0xff));	// S3,S4
	s56=*(pTable+ 8*1024+
		(int)( ((x>>36)&0xf) | ((x>>20)&0xff0 ) ));	// S5,S6
	s78=*(pTable+12*1024+
		(int)( ((x>>24)&0xf00)| ((x>>40)&0xff ) ));	// S7,S8

	r=0;
	r|=((__int64)s12&0xff)|(((__int64)s34&0xff)<<8)|
		(((__int64)s56&0xff)<<16)|(((__int64)s78&0xff)<<24);

	return r;
}

__int64 CDES::shuffle(__int64 d,char *p)
{
	__int64 r=0;

	for(int i=0;i<64;i++){
		if(d & bitTable[p[i]-1])
			r|=bitTable[i];
	}
	return r;
}

__int64 CDES::shuffle32(__int64 x)
{
	char sfTab[32]={			//shuffle table
		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
	};
	__int64 r;

	r=0;
	for(int i=0;i<32;i++){
		if(x & bitTable[sfTab[i]-1])
			r|=bitTable[i];
	}
	return r;
}

CDES::CDES(char *cKey) //=NULL)
{
	int i;
	__int64 bitIs1;

	// set bitTable
	/*for(i=0,bitIs1=1 //0x8000000000000000 // the highest bit 1
		;i<64;i++,bitIs1<<=1)//bitIs1>>=1)
		bitTable[i]=bitIs1;*/

	int j;
	for(i=0;i<8;i++)
		for(bitIs1=0x80,j=0;j<8;j++,bitIs1>>=1)
			bitTable[i*8+j]=((__int64)bitIs1)<<i*8;


	if(cKey==NULL)		// set default keys
		setKey("-SINMIN-");
	else{				//set key;
		setKey(cKey);
	}	

	//allocate memory
	//pTable=new  char[ 4*(4*1024) ];		// I don't know why use this line to cause link error
	pTable=(char *)malloc(4*4*1024);		//allocate memory
	if(pTable==NULL)
		errorNumber=ERR_ALLOCATEMEMORY;

	initializeDES();

}

int CDES::setKey(char *s)
{
	for(int i=0;i<8;i++)
		key[i]=0;

	for(i=0;i<(int)strlen(s);i++){
		key[i]=(*(s+i))<<1;		//push out Odd/even check bit
		if(i>=MAXKEYLENGTH) break;
	}
	calculateSubKey();
	return (int)strlen(s);
}

void CDES::calculateSubKey(void)
{	
	char rotate[16]={			//rotate TIMES for every key
		1,1,2,2,2,2,2,2,
		1,2,2,2,2,2,2,1
	};
	char select1[56]={			// first selection for Keys
								//convert 64bit keys to 56bits(clear odd CheckCode)
		57,49,41,33,25,17, 9,		//for PartC
		 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,		//for partD
		 7,62,54,46,38,30,22,
		14, 6,61,53,45,37,29,
		21,13, 5,28,20,12, 4
	};

	char select2[48]={	// permuted choice key (table)  
						// create a 48bit subkey
		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
	};

	__int64 tempKey,key64;
	int i,j;
	char partC[56],*partD;
	partD=partC+28;

	//convert key to a 64 bits value
	for(i=0,key64=0;i<8;i++)
		key64|=((__int64)key[i])<<i*8;		//force convert

	//convert a bit to  a byte to make algrithom eary
	// and then set initialize  values for C and D
	for(i=0;i<56;i++)
		partC[i]= (key64 & bitTable[select1[i]-1])	? 1:0;

	//calculate 16 subkeys, one by one
	for(i=0;i<16;i++){
		//rotate paryD and partC
		runCircle(partC,rotate[i]);
		runCircle(partD,rotate[i]);
		
		//create a subKey,   from 56bit select 48bit
		for(j=0,tempKey=0;j<48;j++){
			if(partC[select2[j]-1])
				tempKey|=bitTable[j];
		}
		subKey[i]=tempKey;
	}	
}

// circle left shift dat by iTms times
void CDES::runCircle(char *dat, int iTms)
{
	int i,j;
	char cMemory;
	for(i=0;i<iTms;i++){
		cMemory=dat[0];
		for(j=0;j<27;j++)
			dat[j]=dat[j+1];
		dat[j]=cMemory;		//dat[28]
	}
}

BOOL CDES::initializeDES()
{	
	int i,j;
	char cLow,cHigh;

	if(pTable==NULL)return FALSE;	//memory not allocated, error,
									//return false
	
	//calculate table for convert 48 bits to 32 bits
	for(i=0;i<4;i++){
		for(j=0;j<4*1024;j++){
			cLow=cv6to4(i*2+1,j&0x3f);			// LOW 6 BITS
			cHigh=cv6to4(i*2,(j>>6)&0x3f);		//HIGH 6 BITS
			*(pTable+i*4*1024+j)=cLow|(cHigh<<4);
		}
	}
	return TRUE;
}

char CDES::cv6to4(int tabN, char val)
{
	char sTab[8][64]={
		{	/* 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
		}
	};
	int iRow,iPos;
	char r;
	
	iRow=((0x20 & val) ? 2:0) // bit 6( start from 1,not 0)
		+((0x1  & val) ? 1:0); // bit 1(see upper)

	iPos=16*iRow+((val>>1)&0xf);

	r=sTab[tabN][iPos];		//16*iRow+(val>>1) & 0xf];
	return r;
}

CDES::~CDES()
{
	if(pTable!=NULL)		// free memory
		free(pTable);		//delete pTable will cause link error
}

char *CDES::getErrorDescription(int errNum)
{
	char errDesc[][1024]={
		"内存分配出错",				//[0]
		"加密/解密长度不为 8 的整数倍",	//[1]
		"未知错误"				//[2]
	};
	//char 

	switch(errNum){
	case ERR_ALLOCATEMEMORY:
		return errDesc[0];
	case ERR_LENGTH:
		return errDesc[1];
	case ERR_UNKNOW:
		return errDesc[2];
	default:
		return errDesc[2];
	}
}

int CDES::getErrorNumber(void)
{
	return errorNumber;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -