加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

DES加密算法C++实现

发布时间:2020-12-16 07:48:24 所属栏目:百科 来源:网络整理
导读:今天PHP站长网 52php.cn把收集自互联网的代码分享给大家,仅供参考。 #include stdlib.h#include stdio.h#include string.h#define ENCRYPT 1#define DECRYPT 0static void printHex ( char *cmd,int len );static void p

以下代码由PHP站长网 52php.cn收集自互联网

现在PHP站长网小编把它分享给大家,仅供参考

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define ENCRYPT 1
#define DECRYPT 0

static void printHex ( char *cmd,int len );
static void printArray ( const char *In,int len );

static void F_func ( bool In[32],const bool Ki[48] );    // f函数
static void S_func ( bool Out[32],const bool In[48] );   // S盒代替

static void Transform ( bool *Out,bool *In,const char *Table,int len ); // 变换
static void Xor ( bool *InA,const bool *InB,int len );   // 异或
static void RotateL ( bool *In,int len,int loop );    // 循环左移
static void ByteToBit ( bool *Out,const char *In,int bits );  // 字节组转换成位组
static void BitToByte ( char *Out,const bool *In,int bits );  // 位组转换成字节组

// 16位子密钥
static bool SubKey[16][48];

// 64位经过PC1转换为56位 (PC-1)
const static char PC1_Table[56] =
{
	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
};

// 左移
const static char LOOP_Table[16] =
{
	1,1
};

// 排列选择 2 (PC-2)
const static char PC2_Table[48] =
{
	14,24,4,8,16,40,48,56,32
};

// Ri_1(32位)经过变换E后膨胀为48位 (E)  void F_func
static const char E_Table[48] =
{
	32,32,1
};

// 8个4比特合并为32比特的排列 P
const static char P_Table[32] =
{
	16,};

// 经过S盒 S-boxes
const static char S_Box[8][4][16] =
{
	{
		// S1
		{  14,7   },{   0,8   },{   4,0   },{  15,13   }
	},{
		// S2
		{  15,10   },{   3,5   },15   },{  13,9   }
	},{
		// S3
		{  10,1   },{   1,12   }
	},{
		// S4
		{   7,9   },{  10,4   },14   }
	},{
		// S5
		{   2,{  14,6   },14   },{  11,3   }
	},{
		// S6
		{  12,11   },{   9,{
		// S7
		{   4,2   },{   6,{
		// S8
		{  13,{   7,{   2,11   }
	}
};

// 初始排列 (IP)
const static char IP_Table[64] =
{
	58,64,57,7
};

// L16与R16合并后经过IP_1的最终排列 (IP**-1)
const static char IPR_Table[64] =
{
	40,25
};

void Des_SetKey ( const char Key[8] );  //生成子密钥
void Des_Run ( char Out[8],char In[8],bool Type );  //DES算法

void main ( int argc,char *argv[] )
{
	char key[12]={1,8};
	char str[12]="Hello";
	char str2[12];

	//printArray( PC2_Table,sizeof(PC2_Table)/sizeof(PC2_Table[0]) );

	printf ( "Before encrypting: " );
	puts ( str );

	Des_SetKey ( key );

	memset ( str2,sizeof ( str2 ) );
	Des_Run ( str2,str,ENCRYPT );
	printf ( "After  encrypting: " );
	printHex ( str2,8 );

	memset ( str,sizeof ( str ) );
	printf ( "After  decrypting: " );
	Des_Run ( str,str2,DECRYPT );
	puts ( str );

}

void Des_SetKey ( const char Key[8] )
{
	int i;
	static bool K[64],*KL = &K[0],*KR = &K[28];

	ByteToBit ( K,Key,64 );   //转换为二进制

	Transform ( K,K,PC1_Table,56 );   //64比特的密钥K,经过PC-1后,生成56比特的串。

	//生成16个子密钥
	for ( i=0; i<16; i++ )
	{
		//循环左移,合并
		RotateL ( KL,LOOP_Table[i] );
		RotateL ( KR,LOOP_Table[i] );
		Transform ( SubKey[i],PC2_Table,48 );
	}
}

void Des_Run ( char Out[8],bool Type )
{
	int i;
	static bool M[64],tmp[32],*Li = &M[0],*Ri = &M[32];

	//转换为64位的数据块
	ByteToBit ( M,In,64 );

	//IP置换 (初始)
	Transform ( M,M,IP_Table,64 );

	//该比特串被分为32位的L0和32位的R0两部分。

	if ( Type == ENCRYPT )
	{
		//16轮置换
		for ( i=0; i<16; i++ )
		{
			memcpy ( tmp,Ri,32 );

			// R[i] = L[i-1] xor f(R[i-1],K[i])
			F_func ( Ri,SubKey[i] );

			// 2.4.6 Exclusive-or the resulting value with L[i-1].
			// R[I]=P XOR L[I-1]
			Xor ( Ri,Li,32 );

			// L[i] = R[i-1]
			memcpy ( Li,tmp,32 );

		}
	}
	else
	{
		// 如果解密则反转子密钥顺序
		for ( i=15; i>=0; i-- )
		{
			memcpy ( tmp,32 );
			F_func ( Li,SubKey[i] );
			Xor ( Li,32 );
			memcpy ( Ri,32 );
		}
	}

	//R16与L16合并成64位的比特串。R16一定要排在L16前面。R16与L16合并后成的比特串,经过置换IP-1后所得的比特串就是密文。
	Transform ( M,IPR_Table,64 );

	BitToByte ( Out,64 );
}

//将32比特的输入再转化为32比特的输出
void F_func ( bool In[32],const bool Ki[48] )
{
	static bool MR[48];

	//输入Ri-1(32比特)经过变换E后,膨胀为48比特
	Transform ( MR,E_Table,48 );

	//异或
	Xor ( MR,Ki,48 );

	//膨胀后的比特串分为8组,每组6比特。各组经过各自的S盒后,又变为4比特(具体过程见后),合并后又成为32比特。
	S_func ( In,MR );

	//该32比特经过P变换后,输出的比特串才是32比特的f (Ri-1,Ki)。
	Transform ( In,P_Table,32 );
}

void S_func ( bool Out[32],const bool In[48] )
{
	char j,m,n;

	//膨胀后的比特串分为8组,每组6比特。
	for ( j=0; j<8; j++,In+=6,Out+=4 )
	{
		//在其输入In[0],In[1],In[2],In[3],In[4],In[5]中,计算出m=In[0]*2+In[5],n=In[4]+In[3]*2+In[2]*4+In[1]*8,再从Sj表中查出m行,n列的值Smn。将Smn化为二进制,即得Si盒的输出。
		m = ( In[0]<<1 ) + In[5];
		n = ( In[1]<<3 ) + ( In[2]<<2 ) + ( In[3]<<1 ) + In[4];

		ByteToBit ( Out,&S_Box[ ( int ) j][ ( int ) m][ ( int ) n],4 );
	}
}

// 打印指定位置指定长度HEX值
static void printHex ( char *cmd,int len )
{
	int i;

	for ( i=0; i<len; i++ )
	{
		printf ( "[%02X]",( unsigned char ) cmd[i] );
	}
	printf ( "n" );
}

// 打印数组测试用
static void printArray ( const char *In,int len )
{
	int   i;
	char tmp[256];

	memset ( tmp,sizeof ( tmp ) );

	for ( i=0; i<len; i++ )
	{
		tmp[ ( int ) In[i]]=In[i];
	}

	for ( i=0; i<len; i++ )
	{
		printf ( "[%02d]",( unsigned char ) tmp[i] );
	}
	printf ( "n" );
}

void Transform ( bool *Out,int len )
{
	int i;
	static bool tmp[256];

	for ( i=0; i<len; i++ )
	{
		tmp[i] = In[ Table[i]-1 ];
	}
	memcpy ( Out,len );
}

void Xor ( bool *InA,int len )
{
	int i;

	for ( i=0; i<len; i++ )
	{
		InA[i] ^= InB[i];
	}
}

void RotateL ( bool *In,int loop )
{
	static bool tmp[256];               // Sample:  loop=2
	memcpy ( tmp,loop );           // In=12345678 tmp=12
	memcpy ( In,In+loop,len-loop );   // In=345678
	memcpy ( In+len-loop,loop );  // In=34567812
}

// Sample:
// In = [0x01]
// Out = [0x01] [0x00] [0x00] [0x00] [0x00] [0x00] [0x00] [0x00]
void ByteToBit ( bool *Out,int bits )
{
	int i;

	for ( i=0; i<bits; i++ )
	{
		// In[i]的第N位右移N位并和0x01按位"与"运算(N=1~8)
		Out[i] = ( In[i/8]>> ( i%8 ) ) & 1;
	}
}

void BitToByte ( char *Out,int bits )
{
	int i;

	memset ( Out,( bits+7 ) /8 );
	for ( i=0; i<bits; i++ )
	{
		Out[i/8] |= In[i]<< ( i%8 );
	}
}


以上内容由PHP站长网【52php.cn】收集整理供大家参考研究

如果以上内容对您有帮助,欢迎收藏、点赞、推荐、分享。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读