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

📄 des_2005p.cpp

📁 计算机网络安全中的DES加密解密算法
💻 CPP
字号:
typedef unsigned char	word8;
typedef unsigned short	word16;
typedef unsigned long	word32;

#include <iostream.h>
#include <iomanip.h>

// 字节取位数组
word8 B1bit[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};

// 密钥编排函数KS,由8字节的密钥key,生成16个48位的子密钥keyi
// 密钥各位的编号,从第一字节高位开始。明文的位编号也如此。
void KS(word8 *key,word8 (*keyi)[48])
 { word8 i,j,k,l,m,temp,pc1key[56];
   // 密钥置换选择1(PC_1:56位-->56位)数组
   word8 pc1[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,		// C0
      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 };	// D0
	// 密钥位移数组
   word8 movkey[16]={1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};
	// 密钥置换选择2(PC_2:56位-->48位)数组
   word8 pc2[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};
   for (i=0;i<56;i++)   // 进行置换选择PC_1
	{  //密钥的56个有效位经PC_1变位后存于数组pc1key中
      l=pc1[i];
      k=l>>3;
      m=l&07;
      pc1key[i]=(key[k]&B1bit[m])?1:0;
    }   // pc1key的前28元素是C,后28个是D
   for (i=0;i<16;i++)
    {
      for (j=0;j<movkey[i];j++) // 循环左移(往前(高位)移)C、D
       { for (temp=pc1key[0],k=0;k<27;k++) pc1key[k]=pc1key[k+1];
	 pc1key[k]=temp;
	 for (temp=pc1key[28],k=28;k<55;k++) pc1key[k]=pc1key[k+1];
	 pc1key[k]=temp;
       }
      for (j=0;j<48;j++)			// 进行置换选择PC_2
	 keyi[i][j]=pc1key[pc2[j]];
    }
 }

void bit_to_byte(word8 *bt,word8 *bb,word16 n)
{  // 将位bt(8*n位)-->n个字节bb;每个字节中,在前的是高位 
	word16 j,m,k;
   word8 temp;
   for (j=m=0;j<n;j++)
    { for (temp=0,k=0;k<8;k++)
	  { m=j*8+k;
	    temp=(temp<<1)|bt[m];
	  }
      bb[j]=temp;
    }
 }

// 密码函数f(R,Ki)
void frk(word8 *r,word8 *ki,word8 *pr)
 {	// r,ki,pr中每个元素为1个二进制位  
	word8 i,j,k,m,n,x[8],p0[32],Er[48];
    // 比特扩展变换(E:32位-->48位)数组
    word8 E[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};
    // 8个S盒:S1-S8
    word8 S[8][4][16]={
      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,  /* S1 */
      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,  /* S2 */
      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,  /* S3 */
       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,  /* S4 */
       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,  /* S5 */
      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,  /* S6 */
       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,  /* S7 */
      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};  /* S8 */
    // 密码置换(P:32位-->32位)数组
    word8 P[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};
    for (i=0;i<48;i++) Er[i]=r[E[i]];		// 32位扩展成48位
    for (i=0;i<48;i++) Er[i]=Er[i]^ki[i];	// 异或
    for (i=k=0;k<8;k++,i+=6)
	 {  // 8个S盒变换,每个x[i]中保存4位
		 m = (Er[i] << 1)|Er[i+5];
		 n = (Er[i+1]<<3)|(Er[i+2]<<2)|(Er[i+3]<<1)|Er[i+4];
		 x[k] = S[k][m][n];
	 }
    for (i=j=0;i<8;i++)
       for (k=4;k<8;k++)
		 {
			 p0[j]=(x[i]&B1bit[k])?1:0;
			 j++;
		 }
    for (i=0;i<32;i++) pr[i]=p0[P[i]];
 }
// 明文初始置换函数IP
// x为8字节明文,x0为明文经M1置换后的64位
// 明文中的位从第一个字节开始编号,高位在前
void IP(word8 *x,word8 *x0)
 { // 明文初始变位(M1:64位-->64位)数组
   word8 M1[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};
   word8 i,j,k,m;
   for (k=i=0;i<64;i++)
    {  // 8字节明文分解为64位并进行初始变位
       j = M1[i];
       k = j >> 3;
       m = j & 07;
       x0[i] = (x[k] & B1bit[m]) ? 1:0;
    }
 }
//DES加密/解密函数
void DES(word8 *x,word8 *key,word8 *c,word8 mod)
{  // 8字节明文x-->8字节密文c;mod=0:加密  mod=1:解密 
	word8 x0[64],c0[64],keyi[16][48],pr[32],*Li,*Ri,*t;
   word8 i,j,Rnd;
	// 明文初始变位的逆变位(M2:64位-->64位)数组
   word8 M2[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};
   KS(key,keyi);	//生成的16个子密钥存于二维数组keyi中
   IP(x,x0);	//明文x经初始变位后,结果存于x0中
   Li=x0;Ri=x0+32;//Ri指向x0的右边32位
   for (Rnd=0;Rnd<16;Rnd++)
	{  //进行16轮加密/解密
      if (mod==0)j=Rnd;
      else j=15-Rnd;
      frk(Ri,keyi[j],pr);
      for (i=0;i<32;i++) Li[i]=pr[i]^Li[i];	//异或
      t=Li;
      Li=Ri;
      Ri=t;
    }
   for (i=0;i<32;i++) c0[i]=Ri[i];
   for (j=0;j<32;j++,i++) c0[i]=Li[j];
   for (i=0;i<64;i++) x0[i]=c0[M2[i]];        /* M2(R16L16) */
   bit_to_byte(x0,c,8);	//8个字节加密/解密结果存于c中
 }

void main()
 {
   word8 x[9]="Goodbye!";	//明文
   word8 key[8]={0x5b,0x5a,0x57,0x67,0x6a,0x56,0x67,0x6e};//密钥
   word8 i,c[8],x1[8];
   cout<<"明文:";
   for (i=0;i<8;i++) cout<<x[i]<<"  ";
   cout<<"\n密钥:";
   for (i=0;i<8;i++) 
		cout<<setfill('0')<<hex<<(int)key[i]<<" ";
   DES(x,key,c,0);	//加密
   cout<<"\n密文:";
   for (i=0;i<8;i++) 
		cout<<setfill('0')<<hex<<setw(2)<<(int)c[i]<<" ";
   cout<<"\t(ASCII值)\n密文:";
   for (i=0;i<8;i++)
	   cout<<setfill(' ')<<setw(2)<<c[i]<<' ';
   DES(c,key,x1,1);	//解密
   cout<<"(字符)\n解密得到的明文:\n      ";
   for (i=0;i<8;i++) cout<<x1[i]<<"  ";
   cout<<"\n\n";
 }

⌨️ 快捷键说明

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