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】收集整理供大家参考研究 如果以上内容对您有帮助,欢迎收藏、点赞、推荐、分享。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |