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

📄 des.cpp

📁 DES加密算法
💻 CPP
字号:
// DES.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "math.h"

struct Sbox
{
	int element[64];
}S_box[8]={ {14, 0, 4,15,13, 7, 1, 4, 2,14,15, 2,11,13, 8, 1,  //0
			  3,10,10, 6, 6,12,12,11, 5, 9, 9, 5, 0, 3, 7, 8,
			  4,15, 1,12,14, 8, 8, 2,13, 4, 6, 9, 2, 1,11, 7,
			 15, 5,12,11, 9, 3, 7,14, 3,10,10, 0, 5, 6, 0,13},   
			{15, 3, 1,13, 8, 4,14, 7, 6,15,11, 2, 3, 8, 4,14,  //1 
			  9,12, 7, 0, 2, 1,13,10,12, 6, 0, 9, 5,11,10, 5,
			  0,13,14, 8, 7,10,11, 1,10, 3, 4,15,13, 4, 1, 2,  
			  5,11, 8, 6,12, 7, 6,12, 9, 0, 3, 5, 2,14,15, 9},   
			{10,13, 0, 7, 9, 0,14, 9, 6, 3, 3, 4,15, 6, 5,10, //2
			  1, 2,13, 8,12, 5, 7,14,11,12, 4,11, 2,15, 8, 1,
			 13, 1, 6,10, 4,13, 9, 0, 8, 6,15, 9, 3, 8, 0, 7,
			 11, 4, 1,15, 2,14,12, 3, 5,11,10, 5,14, 2, 7,12},   
			{ 7,13,13, 8,14,11, 3, 5, 0, 6, 6,15, 9, 0,10, 3,  //3
			  1, 4, 2, 7, 8, 2, 5,12,11, 1,12,10, 4,14,15, 9,
			 10, 3, 6,15, 9, 0, 0, 6,12,10,11, 1, 7,13,13, 8,
			 15, 9, 1, 4, 3, 5,14,11, 5,12, 2, 7, 8, 2, 4,14},   
			{ 2,14,12,11, 4, 2, 1,12, 7, 4,10, 7,11,13, 6, 1,  //4
			  8, 5, 5, 0, 3,15,15,10,13, 3, 0, 9,14, 8, 9, 6,
			  4,11, 2, 8, 1,12,11, 7,10, 1,13,14, 7, 2, 8,13,
			 15, 6, 9,15,12, 0, 5, 9, 6,10, 3, 4, 0, 5,14, 3},   
			{12,10, 1,15,10, 4,15, 2, 9, 7, 2,12, 6, 9, 8, 5,  //5
			  0, 6,13, 1, 3,13, 4,14,14, 0, 7,11, 5, 3,11, 8,
			  9, 4,14, 3,15, 2, 5,12, 2, 9, 8, 5,12,15, 3,10,
	    	  7,11, 0,14, 4, 1,10, 7, 1, 6,13, 0,11, 8, 6,13},   
			{ 4,13,11, 0, 2,11,14, 7,15, 4, 0, 9, 8, 1,13,10,  // 6
			  3,14,12, 3, 9, 5, 7,12, 5, 2,10,15, 6, 8, 1, 6,
			  1, 6, 4,11,11,13,13, 8,12, 1, 3, 4, 7,10,14, 7,
			 10, 9,15, 5, 6, 0, 8,15, 0,14, 5, 2, 9, 3, 2,12},   
			{13, 1, 2,15, 8,13, 4, 8, 6,10,15, 3,11, 7, 1, 4,  //7
			 10,12, 9, 5, 3, 6,14,11, 5, 0, 0,14,12, 9, 7, 2,
			  7, 2,11, 1, 4,14, 1, 7, 9, 4,12,10,14, 8, 2,13,
			  0,15, 6,12,10, 9,13, 0,15, 3, 3, 5, 5, 6, 8,11}};

////////////////////////////////////////////////////////////////////////////////////////////

/*						获取密钥					*/
/*--------------------------------------------------*/
//从Key.txt中获取64位的密钥存pKey指向的数组
void GetKey( char *pKey )
{
	struct Key8bit
	{
		unsigned a:	4;     //注意ab不能互换
		unsigned b:	4;
	};
	union
	{
		struct Key8bit Keyc;
		char c;
	}union1;

	int i;
	FILE *fp;
	
	char tempc1,tempc2;
	
	fp=fopen("Key.txt","rb");
	for( i=0 ; i<8 ; i++ )
	{
		tempc1=fgetc(fp);
		if(tempc1>='0' && tempc1<='9')
		{
			union1.Keyc.b=tempc1-48;
		}
		else if(tempc1>='a' && tempc1<='f')
		{
			union1.Keyc.b=tempc1-87;
		}
		else
		{
			union1.Keyc.b=tempc1-55;
		}
		tempc2=fgetc(fp);
		if(tempc2>='0' && tempc2<='9')
		{
			union1.Keyc.a=tempc2-48;
		}
		else if(tempc1>='a' && tempc1<='f')
		{
			union1.Keyc.a=tempc2-87;
		}
		else
		{
			union1.Keyc.a=tempc2-55;
		}
		*(pKey+i)=union1.c;
	}
	fclose(fp);		
}

/*					获取比特值						*/
/*--------------------------------------------------*/
//pKey   指针指向数组
//i      表示要获取的第几比特位的值
//返回int型 1 或 0
int GetBitValue(char *pch , int i )
{
	int flag;
	struct Byte
	{
	    unsigned bit7: 1;	
		unsigned bit6: 1;		
		unsigned bit5: 1;		
		unsigned bit4: 1;	
		unsigned bit3: 1;
		unsigned bit2: 1;
		unsigned bit1: 1;	
		unsigned bit0: 1;  
	};
	union
	{
		struct Byte	OneByte;
		char		Tempc;
	}C;

	C.Tempc = *(pch+(i/8));

	switch( (i%8) )
	{
		case 0:	{	
					if(C.OneByte.bit0 == 0)	
						 flag = 0;
					else flag = 1;	
						break;
				}

		case 1:	{
					if(C.OneByte.bit1 == 0)	
						 flag = 0;
					else flag = 1;	
						break;
				}
		case 2:	{
					if(C.OneByte.bit2 == 0)	
						 flag = 0;
					else flag = 1;	
						break;
				}
		case 3:	{
					if(C.OneByte.bit3 == 0)	
						 flag = 0;
					else flag = 1;	
						break;
				}
		case 4:	{
					if(C.OneByte.bit4 == 0)	
						 flag = 0;
					else flag = 1;	
						break;
				}
		case 5:	{
					if(C.OneByte.bit5 == 0)	
						 flag = 0;
					else flag = 1;	
						break;
				}
		case 6:	{
					if(C.OneByte.bit6 == 0)	
						 flag = 0;
					else flag = 1;	
						break;
				}
		case 7:	{
					if(C.OneByte.bit7 == 0)	
						 flag = 0;
					else flag = 1;	
						break;
				}
	}
	return flag;
}

/*					设置比特位						*/
/*--------------------------------------------------*/
//pKeyPC1 指针指向char型数组
//i       表示数组的第几比特位要设置
//flag	  int型1或0 表示第i位的比特位设置值
void SetBitValue(char *pKeyPC1 , int i , int flag)
{
	struct Byte
	{
		unsigned bit7: 1;	
		unsigned bit6: 1;		
		unsigned bit5: 1;		
		unsigned bit4: 1;	
		unsigned bit3: 1;
		unsigned bit2: 1;
		unsigned bit1: 1;	
		unsigned bit0: 1;     
	};
	union
	{
		struct Byte	OneByte;
		char		Tempc;
	}C;
	C.Tempc = *(pKeyPC1+(i/8));
	switch( (i%8) )
	{
		case 0:	C.OneByte.bit0 = flag;	break;
		case 1:	C.OneByte.bit1 = flag;	break;
		case 2:	C.OneByte.bit2 = flag;	break;
		case 3:	C.OneByte.bit3 = flag;	break;
		case 4:	C.OneByte.bit4 = flag;	break;
		case 5:	C.OneByte.bit5 = flag;	break;
		case 6:	C.OneByte.bit6 = flag;	break;
		case 7:	C.OneByte.bit7 = flag;	break;
	}
	*(pKeyPC1+(i/8)) = C.Tempc;
}

/*					置换选择一						*/
/*--------------------------------------------------*/
//  输入8字节的字符数组指针		pKey
//  输出到7字节的数组里			pKeyPC1
void PermutedChoice1( char *pKeyPC1 , char *pKey )
{	
	int i;
	int PC_1[56]={56,48,40,32,24,16, 8,	 0,57,49,41,33,25,17,
				   9, 1,58,50,42,34,26,	18,10, 2,59,51,43,35,
				//    62,54,46,38,30,22,14,6,61,53,45,37,29,21, 
				 //  13,5, 60, 52,44,36,28,20,12,4,27,19,11,3};

				  27,19,11, 3,60,52,44,	36,28,20,12, 4,61,53,
				 45,37,29,21,13, 5,62,	54,46,38,30,22,14, 6};
	int flag;
	for(i=0 ; i<56 ; i++)
	{
		flag = GetBitValue(pKey , PC_1[i] );	
		SetBitValue(pKeyPC1 , i , flag); 	
	}
}

/*						循环移位					*/
/*--------------------------------------------------*/
//		输入pC pD 移位数 LS
//		输出移位后的pC pD 
void LeftShift(int LS, char *pKey)
{
	int	i;
	int tempflag;
	int flag;
	for( ; LS>0 ; LS--)
	{
		tempflag = GetBitValue(pKey , 0);
		for(i=0 ; i<27 ; i++)
		{
			flag = GetBitValue(pKey , i+1);
			SetBitValue(pKey , i , flag);
		}
		SetBitValue(pKey , 27 , tempflag);
	}	
}

/*						置换选择二					*/
/*--------------------------------------------------*/
void PermutedChoice2(char *pSubKey , int i , char *pKeyC , char *pKeyD)
{
	int indexPC2[48]={ 13,16,10,23, 0, 4, 2,27,14, 5,20, 9,22,18,11, 3,
					   25, 7,15, 6,26,19,12, 1,40,51,30,36,46,54,29,39,
					   50,44,32,47,43,48,38,55,33,52,45,41,49,35,28,31};
	int m;
	int flag;
	for(m=0 ; m<48 ; m++)
	{
		if(indexPC2[m] < 28)
		{
			flag = GetBitValue(pKeyC , indexPC2[m]);
		}
		else
		{
			flag = GetBitValue(pKeyD , indexPC2[m]-28);
		}
		SetBitValue(pSubKey , i*48+m , flag);
	}


}

/*					产生16子密钥					*/
/*--------------------------------------------------*/
//	输入pC pD 
//	输出16个子密钥
void ProcessSubkey(char *pSubKey , char *pKeyC , char *pKeyD)
{
	int LS[16] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};		//循环左移
	int i;
					
					
	for(i=0 ; i<16 ; i++)
	{
		LeftShift(LS[i] , pKeyC);
		LeftShift(LS[i] , pKeyD);
		PermutedChoice2(pSubKey , i , pKeyC , pKeyD);
	}
}

/*--------------分割置换选择一后的密钥--------------*/
/*--------------------------------------------------*/
void SplitPermutedKey(char *pKeyC , char *pKeyD , char *pKeyPC1 )
{
	int i;
	int j;
	int flag;
	for(i=0 ; i<28 ; i++)
	{
		flag = GetBitValue(pKeyPC1 , i );
		SetBitValue(pKeyC , i , flag);	
	}

	for(j=0 ; i<56 ; i++,j++)
	{
		flag = GetBitValue(pKeyPC1 , i);
		SetBitValue(pKeyD , j , flag);
	}
}

/*					获取待加密的数据		    	*/
/*--------------------------------------------------*/
void GetData( char *pData )
{
	*(pData+0)='l';    					
	*(pData+1)='e';   
	*(pData+2)='a';
	*(pData+3)='r';
	*(pData+4)='n';
	*(pData+5)='i';
	*(pData+6)='n';
	*(pData+7)='g';
/*	*(pData+0)=86;    					
	*(pData+1)=247;   
	*(pData+2)=29;
	*(pData+3)=246;
	*(pData+4)=182;
	*(pData+5)=9;
	*(pData+6)=234;
	*(pData+7)=165;*/
}

/*					 明文的初始置换IP   			*/
/*--------------------------------------------------*/
void InitialPermutation( char *pData )
{
	int indexIP[64]={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,
				     56,48,40,32,24,16, 8, 0,58,50,42,34,26,18,10, 2,
				     60,52,44,36,28,20,12, 4,62,54,46,38,30,22,14, 6};
	int m;
	int flag;
	char Tempc[8];

	for(m=0 ; m<64 ;m++)
	{
		flag = GetBitValue(pData , indexIP[m]);
		SetBitValue(Tempc , m , flag);
	}

	for(m=0 ; m<64 ;m++)
	{
		flag = GetBitValue(Tempc , m);
		SetBitValue(pData , m , flag);
	}

}

/*						E扩展						*/
/*--------------------------------------------------*/
//pR	为4字节32比特位的字符数组的指针
//pER	为E扩展后6字节48比特位的字符数组指针
void ExpansionE(char *pER , char *pR)
{
	int indexE[48]={31, 0, 1, 2, 3, 4, 3, 4, 5, 6, 7, 8,
					 7, 8, 9,10,11,12,11,12,13,14,15,16,
					15,16,17,18,19,20,19,20,21,22,23,24,
					23,24,25,26,27,28,27,28,29,30,31, 0};
    int		m;
	int		flag;

	for(m=0 ; m<48 ; m++)
	{
		flag = GetBitValue(pR , indexE[m]);
		SetBitValue(pER , m , flag);
	}	
}

/*						置换P						*/
/*--------------------------------------------------*/
void PermutationP( char *pR )
{
	int indexP[32]={15, 6,19,20,28,11,27,16,
					 0,14,22,25, 4,17,30, 9,
					 1, 7,23,13,31,26, 2, 8,
					18,12,29, 5,21,10, 3,24};
	int m;
	int flag;
	char Tempc[4];

	for(m=0 ; m<32 ;m++)
	{
		flag = GetBitValue(pR , indexP[m]);
		SetBitValue(Tempc , m , flag);
	}

	for(m=0 ; m<32 ;m++)
	{
		flag = GetBitValue(Tempc , m);
		SetBitValue(pR , m , flag);
	}
}

/*					进入S_boxes						*/
/*--------------------------------------------------*/
void SboxFunction(char *pR , char *pER)
{
	int i,k;	
	int value4,value6;
	int flag;
						
	for(i=0 ; i<8 ; i++)
	{
		value6 = 0;
		for(k=0 ; k<6 ; k++)
		{
			flag   = GetBitValue(pER , i*6+k);
			if(flag == 1)
			{
				value6 = value6 + pow(2 , 6-k-1);
			}
		}
		value4 = S_box[i].element[value6];

		for(k=0 ; k<4 ; k++)
		{
			if(value4 >= pow(2 , 4-k-1))
			{
				flag   = 1;
				value4 = value4-pow(2 , 4-k-1);
				SetBitValue(pR , i*4+k ,flag);
			}
			else 
			{
				flag = 0;				
				SetBitValue(pR , i*4+k ,flag);
			}
		}
	}
}

/*						轮函数						*/
/*--------------------------------------------------*/
void FFunction( char *pR , char *pSubKey , int i)
{		

	char	ER[6];	
	int		j;

	ExpansionE(ER , pR);
											
	for(j=0 ; j<6 ; j++)
	{
	//	ER[j] = ER[j] ^ (*(pSubKey+6*(16-1-i)+j));
		ER[j] = ER[j] ^ (*(pSubKey+6*(i)+j));
	}					  
						

	SboxFunction( pR , ER );
						

	PermutationP( pR );		
							
}

/*					   分割明文数据		    		*/
/*--------------------------------------------------*/
// 输入64位明文
// 输出各32位的明文
void SplitData(char *pL , char *pR , char *pData)
{
	int m , n;
	for(m=0 ; m<4 ; m++)
	{
		*(pL+m) = *(pData+m);
	}
	for(n=0 ; n<4 ; n++,m++)
	{
		*(pR+n) = *(pData+m);
	}
}

/*				合并两部分加密数据					*/
/*--------------------------------------------------*/
void MergeEncryptedData(char *pEncryptedData , char *pL , char *pR)
{
	int m,n;
	for(m=0 ; m<4 ; m++)
	{
		*(pEncryptedData+m) = *(pL+m);
	}
	for(n=0 ; n<4 ; n++,m++)
	{
		*(pEncryptedData+m) = *(pR+n);
	}
}

/*			          逆初始置换					*/
/*--------------------------------------------------*/
void FinalPermutation( char *pEncryptedData )
{
	int indexIP_1[64]={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,32, 0,40, 8,48,16,56,24};
	int m;
	int flag;
	char Tempc[8];

	for(m=0 ; m<64 ; m++)
	{
		flag = GetBitValue(pEncryptedData , indexIP_1[m]);
		SetBitValue(Tempc , m , flag);
	}
	for(m=0 ; m<64 ; m++)
	{
		flag = GetBitValue(Tempc , m);
		SetBitValue(pEncryptedData , m , flag);
	}
}

/*------------------主函数部分-------------------*/
int main(int argc, char* argv[])
{												
	char Key[8];						
	GetKey( Key );					
	
    Key[0] = 'c';
	Key[1] = 'o';
	Key[2] = 'm';
	Key[3] = 'p';
	Key[4] = 'u';
	Key[5] = 't';
	Key[6] = 'e';
	Key[7] = 'r';
                    
	char KeyPC1[7];
	PermutedChoice1( KeyPC1 , Key );
	
	char KeyC[4];					//KeyC共有32比特位 其实只需要前28个比特位 后4比特位没有使用
	char KeyD[4];					//KeyD共有32比特位 其实只需要前28个比特位 后4比特位没有使用
	SplitPermutedKey(KeyC , KeyD , KeyPC1);	//1.2.2 Split the permuted key into two halves. 

    char SubKey[6*16];					//16个子密钥 每个密钥有6个字节长 48比特位
	ProcessSubkey(SubKey , KeyC , KeyD);
					
					 								
	char Data[8];
	GetData( Data );					
		


	InitialPermutation( Data );		
	
	char L[4],R[4];
	SplitData(L , R , Data);				

	int i,j;						
	char TempL[4];
	for(i=0 ; i<16 ; i++)
	{														
		for(j=0 ; j<4 ; j++)
		{
			TempL[j] = L[j];
			L[j]     = R[j];
		}					
			
		FFunction( R , SubKey , i);	
					
		for(j=0 ; j<4 ; j++)
		{			
			R[j]=R[j]^TempL[j];		
		}					
	}

	char	EncryptedData[8];
	MergeEncryptedData(EncryptedData , R , L);

	FinalPermutation( EncryptedData );
	
	printf("Game Over!\n");

	return 0;
}

/*------------------DES加密代码到此结束------------------*/

⌨️ 快捷键说明

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