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

📄 mydes.cpp

📁 DES算法的介绍和实现, C++语言实现
💻 CPP
字号:
#include <stdio.h>
#include <stdlib.h>
typedef unsigned char		U08;
typedef unsigned long		U32;

static U32 wz_leftandtab[3] = {0x0 , 0x80000000 , 0xc0000000 } ;

//****密钥移位表******************************************************
static U08 wz_lefttable[16] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};
//********************************************************************


//****密钥初始置换表************************
static U08 wz_keyleft[28] = {
   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
}; 
static U08 wz_keyright[28] ={
	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
};
//**************************************************


//****56位密钥选取48位密钥表********************************
static U08 wz_keychoose[48] ={
    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
};
 //**********************************************************


 
 //****64位数据初始置换表***************************
static U08  wz_pc1[64] = {/*第一次转换时用*/
       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 
} ;
//**********************************************************


//****right由32位扩展成48位表*********************
static U08 exptab3[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 
};
//********************************************************

static U32  wz_pc2[64] ={ 
    0x80000000L,0x40000000L,0x20000000L,0x10000000L,
	 0x8000000L, 0x4000000L, 0x2000000L, 0x1000000L,
	  0x800000L,  0x400000L,  0x200000L,  0x100000L,   
	   0x80000L,   0x40000L,   0x20000L,   0x10000L, 
	    0x8000L,    0x4000L,    0x2000L,    0x1000L, 
         0x800L,     0x400L,     0x200L,     0x100L, 
	      0x80L,      0x40L,	  0x20L,      0x10L,     
		   0x8L,       0x4L,       0x2L,       0x1L,

	0x80000000L,0x40000000L,0x20000000L,0x10000000L,
	 0x8000000L, 0x4000000L, 0x2000000L, 0x1000000L,
	  0x800000L,  0x400000L,  0x200000L,  0x100000L,   
	   0x80000L,   0x40000L,   0x20000L,   0x10000L, 
	    0x8000L,    0x4000L,    0x2000L,    0x1000L, 
         0x800L,     0x400L,     0x200L,     0x100L, 
	      0x80L,      0x40L,	  0x20L,      0x10L,     
		   0x8L,       0x4L,       0x2L,       0x1L,
};



//****right由48位压缩成32位表**********************
static U08 SP[8][64] ={
	{
		0xe,0x0,0x4,0xf,0xd,0x7,0x1,0x4,
		0x2,0xe,0xf,0x2,0xb,0xd,0x8,0x1,  //0xb 0x1
		0x3,0xa,0xa,0x6,0x6,0xc,0xc,0xb,
		0x5,0x9,0x9,0x5,0x0,0x3,0x7,0x8,
		0x4,0xf,0x1,0xc,0xe,0x8,0x8,0x2,
		0xd,0x4,0x6,0x9,0x2,0x1,0xb,0x7,
		0xf,0x5,0xc,0xb,0x9,0x3,0x7,0xe,
		0x3,0xa,0xa,0x0,0x5,0x6,0x0,0xd  
	},	
	{ 
		0xf,0x3,0x1,0xd,0x8,0x4,0xe,0x7,
		0x6,0xf,0xb,0x2,0x3,0x8,0x4,0xf,
		0x9,0xc,0x7,0x0,0x2,0x1,0xd,0xa,
		0xc,0x6,0x0,0x9,0x5,0xb,0xa,0x5,
		0x0,0xd,0xe,0x8,0x7,0xa,0xb,0x1,
		0xa,0x3,0x4,0xf,0xd,0x4,0x1,0x2,
		0x5,0xb,0x8,0x6,0xc,0x7,0x6,0xc,
		0x9,0x0,0x3,0x5,0x2,0xe,0xf,0x9
	},    
	{ 
		0xa,0xd,0x0,0x7,0x9,0x0,0xe,0x9,
		0x6,0x3,0x3,0x4,0xf,0x6,0x5,0xa,
		0x1,0x2,0xd,0x8,0xc,0x5,0x7,0xe,
		0xb,0xc,0x4,0xb,0x2,0xf,0x8,0x1,
		0xd,0x1,0x6,0xa,0x4,0xd,0x9,0x0,
		0x8,0x6,0xf,0x9,0x3,0x8,0x0,0x7,
		0xb,0x4,0x1,0xf,0x2,0xe,0xc,0x3,
		0x5,0xb,0xa,0x5,0xe,0x2,0x7,0xc                                          
	},       
	{ 
		0x7,0xd,0xd,0x8,0xe,0xb,0x3,0x5,
		0x0,0x6,0x6,0xf,0x9,0x0,0xa,0x3,
		0x1,0x4,0x2,0x7,0x8,0x2,0x5,0xc,
		0xb,0x1,0xc,0xa,0x4,0xe,0xf,0x9,
		0xa,0x3,0x6,0xf,0x9,0x0,0x0,0x6,
		0xc,0xa,0xb,0xa,0x7,0xd,0xd,0x8,
		0xf,0x9,0x1,0x4,0x3,0x5,0xe,0xb,
		0x5,0xc,0x2,0x7,0x8,0x2,0x4,0xe                         
	},	
	{ 
		0x2,0xe,0xc,0xb,0x4,0x2,0x1,0xc,
		0x7,0x4,0xa,0x7,0xb,0xd,0x6,0x1,
		0x8,0x5,0x5,0x0,0x3,0xf,0xf,0xa,
		0xd,0x3,0x0,0x9,0xe,0x8,0x9,0x6,
		0x4,0xb,0x2,0x8,0x1,0xc,0xb,0x7,
		0xa,0x1,0xd,0xe,0x7,0x2,0x8,0xd,
		0xf,0x6,0x9,0xf,0xc,0x0,0x5,0x9,
		0x6,0xa,0x3,0x4,0x0,0x5,0xe,0x3
	},      
	{ 
		0xc,0xa,0x1,0xf,0xa,0x4,0xf,0x2,
		0x9,0x7,0x2,0xc,0x6,0x9,0x8,0x5,
		0x0,0x6,0xd,0x1,0x3,0xd,0x4,0xe,
		0xe,0x0,0x7,0xb,0x5,0x3,0xb,0x8,
		0x9,0x4,0xe,0x3,0xf,0x2,0x5,0xc,
		0x2,0x9,0x8,0x5,0xc,0xf,0x3,0xa,
		0x7,0xb,0x0,0xe,0x4,0x1,0xa,0x7,
		0x1,0x6,0xd,0x0,0xb,0x8,0x6,0xd
	},      
	{ 
		0x4,0xd,0xb,0x0,0x2,0xb,0xe,0x7,
		0xf,0x4,0x0,0x9,0x8,0x1,0xd,0xa,
		0x3,0xe,0xc,0x3,0x9,0x5,0x7,0xc,
		0x5,0x2,0xa,0xf,0x6,0x8,0x1,0x6,
		0x1,0x6,0x4,0xb,0xb,0xd,0xd,0x8,
		0xc,0x1,0x3,0x4,0x7,0xa,0xe,0x7,
		0xa,0x9,0xf,0x5,0x6,0x0,0x8,0xf,
		0x0,0xe,0x5,0x2,0x9,0x3,0x2,0xc
	},       
	{ 
		0xd,0x1,0x2,0xf,0x8,0xd,0x4,0x8,
		0x6,0xa,0xf,0x3,0xb,0x7,0x1,0x4,
		0xa,0xc,0x9,0x5,0x3,0x6,0xe,0xb,
		0x5,0x0,0x0,0xe,0xc,0x9,0x7,0x2,
		0x7,0x2,0xb,0x1,0x4,0xe,0x1,0x7,
		0x9,0x4,0xc,0xa,0xe,0x8,0x2,0xd,
		0x0,0xf,0x6,0xc,0xa,0x9,0xd,0x0,
		0xf,0x3,0x3,0x5,0x5,0x6,0x8,0xb
	} 
};
//************************************************************


//****32位right换位表***************************************
static U08 wz_pc3[32] = {
    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
} ;
//**************************************************************



//****最后一次换位表**********************************
static U08 wz_pc4[64] = { /*最后一次调整*/
       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
};
 //************************************************************

U32 g_outkey[16][2] = {0};		//输出的key  (16组48bits)
U32 g_bufkey[2] = {0};	

void des(U08 *data, U08 *key);
void handle_data(U32 *left);
void makedata(U32  *left, U32  *right, U32 number); 
void makefirstkey(U32 *keyP);
void makekey(U32 *keyleft, U32 *keyright, U32 number);  /*输入密钥的地址,一个32位的*/

void main()
{
	int i;
	U08 data[8]={'g','n','u','e','m','a','c','s'};
	U08  key[8]={'s','t','a','l','l','m','a','n'};
//	U08 data[8]={0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88};		//数据data[8]
//	U08 key[8] ={0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80};		//密钥Key[8]

	printf("\n/*******64bit data******/\n");
	for(i=0;i<8;++i)
	{
		printf("0x%02x   ",data[i]);
	}
	
	printf("\n/*******64bit key******/\n");
	for(i=0;i<8;++i)
	{
		printf("0x%02x   ",key[i]);
	}

	des(data,key);

	printf("\n/*******64bit endata******/\n");
	for(i=0;i<8;i++)
	{
		printf("0x%02x  ",data[i]);
	}
	printf("\n");
}

void des(U08 *data ,U08 *key)
{  
	makefirstkey((U32 *)key);	//产生密钥	
	handle_data((U32 *)data);	//加密数据
	
}

void makefirstkey(U32 *keyP)
{
	int j; 
	U32 *Pkey;
	U32 *Pbufkey;	
	Pbufkey = (U32*)g_bufkey;
	Pkey = (U32*)keyP;

//	for(j=0;j<2;++j)
//	{
//		printf("Pbufkey[%d] = 0x%08x\n",j,Pbufkey[j]);
//	}
//
//	for(j=0;j<2;++j)
//	{
//		printf("   Pkey[%d] = 0x%08x\n",j,Pkey[j]);
//	}
	
	for(j = 0 ;j < 28; j++)			//初始置换密钥	
	{
		
//*********实现了查表移位操作**************************************************************
		if(wz_keyleft[j] > 32)		//置换表中的数字大于32,则取Pkey[1] 
		{
			if(Pkey[1]&wz_pc2[wz_keyleft[j]-1])		//wz_pc2[]取得wz_keyleft[j]这一位的值
			{
				Pbufkey[0] |= wz_pc2[j];			//例如:j=0时将第57位移到第1位
			}
		}
		else
		{
			if(Pkey[0]&wz_pc2[wz_keyleft[j]-1])
			{
				Pbufkey[0] |= wz_pc2[j];
			}
		}
//*****************************************************************************************
		
		if(wz_keyright[j] > 32) 
		{
			if(Pkey[1]&wz_pc2[wz_keyright[j]-1])
			{
				Pbufkey[1] |= wz_pc2[j];
			}
		}
		else
		{
			if(Pkey[0]&wz_pc2[wz_keyright[j]-1])
			{
				Pbufkey[1] |= wz_pc2[j];
			}
		}
	}						//Pbufkey[0,1] 就是初始置换后的密钥
	
//	for(j=0;j<2;++j)
//	{
//		printf("Pbufkey[%d] = 0x%08X\n",j,Pbufkey[j]);
//	}
	
	for(j=0; j<16; j++)
	{
		makekey(&Pbufkey[0], &Pbufkey[1], (U32)j);	

//		for(int i=0;i<2;++i)
//		{
//			printf("g_outkey[%d][%d] = 0x%08X\n",j,i,g_outkey[j][i]);
//		}
	}	
}

void makekey(U32 *keyleft, U32 *keyright, U32 number)	/*输入密钥的地址,一个32位的*/
{
	int j; 
	U32 tmpkey[2] ={0};
	U32 *Ptmpkey = (U32*)tmpkey;	//用来存放最高一位或两位     
	U32 *Poutkey = (U32*)&g_outkey[number]; 

//************密钥移位操作********************************************	
	
	
	*Ptmpkey = *keyleft&wz_leftandtab[wz_lefttable[number]];    /*要最高的一位或两位*/       
	Ptmpkey[1] = *keyright&wz_leftandtab[wz_lefttable[number]];              
	if(wz_lefttable[number] == 1)	//循环左移1位28bit的数据即是将最高位移到最后一位,其他左移一位
	{
		*Ptmpkey >>= 27;		//移到最后一位
		Ptmpkey[1] >>= 27;
	}
	else
	{
		*Ptmpkey >>= 26;		//移到最后两位
		Ptmpkey[1] >>= 26;                    
	}
	
//	for(j=0;j<2;++j)
//	{
//		printf("Ptmpkey[%d] = 0x%08x\n",j,Ptmpkey[j]);
//	}

	Ptmpkey[0] &= 0xfffffff0;		//取U32中前28bits有效位
	Ptmpkey[1] &= 0xfffffff0;
	
	/*得到高位的值*/
	*keyleft <<= wz_lefttable[number];
	*keyright <<= wz_lefttable[number];
	
//	printf(" keyleft = 0x%08x\n",*keyleft);
//	printf("keyright = 0x%08x\n",*keyright);


	*keyleft |= Ptmpkey[0] ;	//加上最后一位
	*keyright |= Ptmpkey[1] ; 
	
//	printf(" keyleft = 0x%08x\n",*keyleft);
//	printf("keyright = 0x%08x\n",*keyright);
	
//************密钥移位操作********************************************

	Ptmpkey[0] = 0;		//将Ptmpkey[0,1]置为0
	Ptmpkey[1] = 0;
    
//	printf("keyright = 0x%08x\n",*keyright);

	/*从56位中选出48位*/
	for(j = 0; j < 48; j++)
	{
		if(j < 24)
		{
			
			if(*keyleft&wz_pc2[wz_keychoose[j]-1])
			{
				Poutkey[0] |= wz_pc2[j];
			}  		
		}          		
		else /*j>=24*/
		{  	
			if(*keyright&wz_pc2[(wz_keychoose[j]-28-1)])		//56bits中后28bits   ???
			{
				Poutkey[1] |= wz_pc2[j-24];		//从wz_pc2[0]开始			
			}   			
		}
	}	
}

void handle_data(U32 *left)
{
	int number = 0 ,j = 0;   
	U32 *right = &left[1];
	U32 tmp = 0;       
	U32 tmpbuf[2] = {0};   	

//	printf(" left = 0x%08x\n",*left);
//	printf("right = 0x%08x\n",*right);
	
//**************64bits data初始换位**********************************************
	for(j = 0; j < 64; j++)
	{
		if(j < 32) 
		{
			if(wz_pc1[j] > 32)			//属于right
			{
				if(*right&wz_pc2[wz_pc1[j]-1])
				{ 
					tmpbuf[0] |= wz_pc2[j];
				}
			}
			else						//属于left
			{
				if(*left&wz_pc2[wz_pc1[j]-1])
				{
					tmpbuf[0] |= wz_pc2[j];
				}
			}
		}
		else
		{
			if(wz_pc1[j] > 32)         /*属于right*/
			{
				if(*right&wz_pc2[wz_pc1[j]-1])
				{
					tmpbuf[1] |= wz_pc2[j];
				}
			}
			else
			{
				if(*left&wz_pc2[wz_pc1[j]-1] )
				{
					tmpbuf[1] |= wz_pc2[j] ;
				}
			}
		}
	}

	*left  = tmpbuf[0];
	*right = tmpbuf[1];
	
//	printf(" left = 0x%08x\n",*left);
//	printf("right = 0x%08x\n",*right);
	
//********************************************************************************

	tmpbuf[0] = 0 ;
	tmpbuf[1] = 0 ;

	//加密
	for(number = 0; number < 16; number++)
	{          
		makedata(left, right, (U32)number);
	}

	//解密
//	for(number = 15; number >= 0; number--)
//	{            
//		makedata( left , right ,(U32)number);
//	}

	
	//交换回来   /*最后一轮操作不交换左右值*/	
	tmp = *left;
	*left = *right;
	*right = tmp;        
	
//******************数据整理 最后一次调整wz_pc4[64]*************************************
	
	for(j = 0; j < 64; j++)
	{
		if(j < 32) 
		{
			if(wz_pc4[j] > 32)/*属于right*/
			{
				if (*right&wz_pc2[wz_pc4[j]-1])
				{
					tmpbuf[0] |= wz_pc2[j];
				}
			}
			else
			{
				if(*left&wz_pc2[wz_pc4[j]-1])
				{
					tmpbuf[0] |= wz_pc2[j];
				}
			}
		}
		else
		{
			if(wz_pc4[j] > 32)/*属于right*/
			{
				if(*right&wz_pc2[wz_pc4[j]-1])
				{
					tmpbuf[1] |= wz_pc2[j];
				}
			}
			else
			{
				if(*left&wz_pc2[wz_pc4[j]-1])
				{
					tmpbuf[1] |= wz_pc2[j];
				}
			}
		}
	}
	
	*left =  tmpbuf[0];
	*right = tmpbuf[1];

	printf("\n0x%08X\n",*left);
	printf("0x%08X\n",*right);
//*****************************************************************************************
}


void makedata(U32  *left ,U32  *right ,U32 number) 
{
	int j; 
	U32 oldright = *right;         
	U08 rexpbuf[8] = {0};
	U32 datatmp = 0;        
	U32 exp[2] = {0};  
	
//****************** right由32位扩展成48位*************************************************	
	for(j = 0; j < 48; j++)
	{
		/*两个32位,每个存放24位*/
		if(j < 24)
		{
			if(*right&wz_pc2[exptab3[j]-1])
			{
				exp[0] |= wz_pc2[j];
			}            
		}            
		else
		{
			if(*right&wz_pc2[exptab3[j]-1])
			{
				exp[1] |= wz_pc2[j-24];
			}
		}
	}
//****************************************************************************************	

//********扩展后的48位right与第i次迭代生成的48位加密密钥进行按位异或操作******************
	for (j = 0; j < 2; j++)
	{            
		exp[j] ^= g_outkey[number][j];
	}    
//*****************************************************************************************

    
//********把48位的right值转换成32位的right值***********************************************	
	exp[1] >>= 8;	//前24bits为有效值右移8位
	rexpbuf[7] = (U08)(exp[1]&0x0000003fL);		//取出最后6位
	exp[1] >>= 6;	//继续右移6位,然后取出
	rexpbuf[6] = (U08)(exp[1]&0x0000003fL);
	exp[1] >>= 6;
	rexpbuf[5] = (U08)(exp[1]&0x0000003fL);
	exp[1] >>= 6;
	rexpbuf[4] = (U08)(exp[1]&0x0000003fL);
	exp[0] >>= 8;
	rexpbuf[3] = (U08)(exp[0]&0x0000003fL);     
	exp[0] >>= 6;
	rexpbuf[2] = (U08)(exp[0]&0x0000003fL);
	exp[0] >>= 6;
	rexpbuf[1] = (U08)(exp[0]&0x0000003fL);
	exp[0] >>= 6;
	rexpbuf[0] = (U08)(exp[0]&0x0000003fL);     
	exp[0] = 0;
	exp[1] = 0;
	
//rexpbuf[0]查表1,rexpbuf[1]查表2,...	
	*right = 0;
	for(j = 0; j < 7; j++)
	{
		*right |= SP[j][rexpbuf[j]-1];	   //( rexpbuf[j]-1 )???
		*right<<= 4;
	}
	*right|= SP[j][rexpbuf[j]-1];
//*************************************************************************************************	

//************又要换位了****************************************************************************	
	datatmp = 0;
	for(j = 0; j < 32; j++)
	{
		if(*right&wz_pc2[wz_pc3[j]-1])
		{
			datatmp |= wz_pc2[j];
		}
	}
	*right = datatmp;
//****************************************************************************************************	

	/*一轮结束收尾操作*/              	
	*right ^= *left;       
	*left = oldright;
}

⌨️ 快捷键说明

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