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

📄 des.cpp.txt

📁 近代分组密码算法(DES)
💻 TXT
📖 第 1 页 / 共 2 页
字号:
// des.cpp : Defines the entry point for the console application.
//
// des.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <stdio.h>
#include <memory.h>
#include <windows.h>
#include <iostream.h> 
#include <malloc.h>
#include "fstream.h"

char* pstroutput=(char *)malloc(1024*1024);//记录所有的字符输出
char* pstroutput0=pstroutput;//记下初始位置。
//扩展选排阵
char ei[] =
{
	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
};
//密钥选排阵 64bits->56bits
char pc1[] =			  /* Permuted choice table (key)  */
{
		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
};
//密钥生成的循环左移表
char totRot[] = 		  /* Number left rotations of pc1  */
{
	1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28
}; /* totRot[] */
//压缩选排阵56bits->48bits
char pc2[] =			  /* Permuted choice key (table)   */
{
		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
}; /* pc2[] */


/* 8 6-bit subkeys for each of 16 rounds, initialized by SetKey() */
unsigned char kn[16][8];

/* bit 0 is left-most in byte */
int byteBit[] =
{
	0200, 0100, 040, 020, 010, 04, 02, 01 //128,64,32,16,8,4,2,1以8进制表示的。
}; /* byteBit[] */

//用于手工运算验证可以不实现
void SetKey(int doEncrypt,unsigned char *key)
{
	  char			 pc1m[56];		/* Place to modify pc1 into */
	  char			 pcr[56];		/* Place to rotate pc1 into */
	  register int	 i ,j , k;
	  int			 m;
	  if(doEncrypt) pstroutput+=sprintf(pstroutput,"用户输入的64位密钥如下:\n二进制									十六进制\n");
	  if (doEncrypt)
	  {
		  pstroutput+=sprintf(pstroutput,"\n");
		  for (j = 0; j < 8; j++)	pstroutput+=sprintf(pstroutput,"%d\t",j);
	  }
	  if (doEncrypt) pstroutput+=sprintf(pstroutput,"\n");
	  if (doEncrypt) pstroutput+=sprintf(pstroutput,"\n");
	  
	  for (j = 0; j < 64; j++)
	  {
		  k = j;	  /* Integer bit location 将起点定到从0起*/
		  m = k & 07;		   /* find bit	归到一个字节里的哪一位(000-111  */
		  
		  if(doEncrypt) pstroutput+=sprintf(pstroutput,"%d\t", (key[k >> 3] & byteBit[m]) ? 1 : 0);
		  //k >> 3找到所第几位所属字节,再求于字节中第几位
		  if ((j+1)%8==0 && doEncrypt)	pstroutput+=sprintf(pstroutput,"	0X%0X\n",key[k >> 3]);
	  } /* end of for j */
	  if (doEncrypt)
	  {
		  pstroutput+=sprintf(pstroutput,"\n");
		  for (j = 56; j < 64; j++) pstroutput+=sprintf(pstroutput,"%d\t",j);
	  }
	  if (doEncrypt) pstroutput+=sprintf(pstroutput,"\n");
	  /* Clear key schedule */
	  if(doEncrypt)
	  {
		  pstroutput+=sprintf(pstroutput,"/******************步骤1:子密钥处理开始**************************/\n");
		  pstroutput+=sprintf(pstroutput,"步骤1-1:去奇偶校验位(每个字节最左边的位),而后重排56位:\n");
	  }
	  for (i = 0; i < 16; i++)
	  {
		  for (j = 0; j < 8; j++)
			  kn[i][j] = 0;//密钥清零
	  } /* end of for i */
	  if (doEncrypt) pstroutput+=sprintf(pstroutput,"L 28位:\n");
	  for (j = 0; j < 28; j++)
	  {
		  if (doEncrypt)
		  {
			  pstroutput+=sprintf(pstroutput,"%02d ", pc1[j]);
			  if ((j+1)%7==0 && doEncrypt) pstroutput+=sprintf(pstroutput,"|  ");
			  //if ((j+1)%24==0 && doEncrypt)pstroutput+=sprintf(pstroutput,"\n");
		  } 
	  }
	  if (doEncrypt) pstroutput+=sprintf(pstroutput,"\n");
	  for (j = 0; j < 56; j++)
	  {//pc1[0]=57,k=56,m=0x00,56>>3=0x7在第7字节,第0位,
		  //每个字节的起始编号位不再是校验位而是其右1位,56个位都左移1位即-1
		  //校验位:0,8,16,8k位
		  k = pc1[j];	   /* Integer bit location 每字节都去了1校验位,*/
		  m = k & 07;		   /* find bit	归到一个字节里的哪一位(000-111  */
		  if(doEncrypt) pstroutput+=sprintf(pstroutput,"%d  ", (key[k >> 3] & byteBit[m]) ? 1 : 0);
		  //k >> 3找到所第几位所属字节,再求于字节中第几位
		  if (j==27 && doEncrypt)
		  {
			  pstroutput+=sprintf(pstroutput,"\nR 28位:\n");
			  for (int tempj = 28; tempj < 56; tempj++)
			  {
				  if (doEncrypt)
				  {
					  pstroutput+=sprintf(pstroutput,"%02d ", pc1[tempj]);
					  if ((tempj+1)%7==0 && doEncrypt) pstroutput+=sprintf(pstroutput,"|  ");
					  //if ((j+1)%24==0 && doEncrypt)pstroutput+=sprintf(pstroutput,"\n");
				  } 
			  }
			  //if (doEncrypt) pstroutput+=sprintf(pstroutput,"\n");
		  }
		  if ((j+1)%7==0 && doEncrypt) pstroutput+=sprintf(pstroutput,"	");
		  if ((j+1)%28==0 && doEncrypt) pstroutput+=sprintf(pstroutput,"\n");
		  
	  } /* end of for j */
	  
	  /* Convert pc1 to bits of key */
	  for (j = 0; j < 56; j++)
	  {
		  k = pc1[j];	   /* Integer bit location 将起点定到从0起*/
		  m = k & 07;		   /* find bit	归到一个字节里的哪一位(000-111  */
		  pc1m[j] = (key[k >> 3] & byteBit[m]) ? 1 : 0;//k >> 3找到所第几位所属字节,再求于字节中第几位
	  } /* end of for j */
	  
	  /* Key chunk for each iteration */
	  for (i = 0; i < 16; i++)
	  {
		  /* rotate pc1 the right amount */
		  for (j = 0; j < 56; j++)
		  {
			  //循环左移:即用右边(编号大)的位去写左边的(编号小)的位
			  k 	 = j + totRot[i];/*static const char totRot[] = 1, 2(1+1), 4(1+1+2+2,教材上前面左移几项位数之和), 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28};*/
			  pcr[j] = pc1m[(k < (j < 28 ? 28 : 56)) ? k : k - 28];//(j < 28 ? 28 : 56):取28则左半,取56右半,k - 28表示循环移位的
			  
			  if( doEncrypt)
			  {
				  if (j==0)
				  {
					  if(i==0) pstroutput+=sprintf(pstroutput,"/******************步骤1-2:生成子密钥**************************/\n");
					  if(i==0)pstroutput+=sprintf(pstroutput,"步骤1-2-%d-1:第%d轮循环左移,左移%d位后:\n",i,i,totRot[i]);
					  else pstroutput+=sprintf(pstroutput,"步骤1-2-%d-1:第%d轮循环左移累计%d位,在前基础上再左移%d位后:\n",i,i,totRot[i],totRot[i]-totRot[i-1]);
					  pstroutput+=sprintf(pstroutput,"左28位:\n");
				  }
				  pstroutput+=sprintf(pstroutput,"%d", pc1m[(k < (j < 28 ? 28 : 56)) ? k : k - 28]); //(j < 28 ? 28 : 56):取28则左半,取56右半,k - 28表示循环移位的
				  if (j==27) pstroutput+=sprintf(pstroutput,"\n右28位:");
				  if ((j+1)%7==0) pstroutput+=sprintf(pstroutput,"	");
				  if ((j+1)%28==0 && doEncrypt) pstroutput+=sprintf(pstroutput,"\n");
			  }
		  } /* end of for j */
		  if( doEncrypt)pstroutput+=sprintf(pstroutput,"步骤1-2-%d-2:第%d轮循环左移,累计左移%d位后左右合并得:\n",i,i,totRot[i]);
		  if( doEncrypt)for (j = 0; j < 56; j++)
		  {
			  pstroutput+=sprintf(pstroutput,"%d",(j%7+1));
			  if ((j+1)%7==0) pstroutput+=sprintf(pstroutput,"	");
		  }
		  
		  
		  if( doEncrypt)pstroutput+=sprintf(pstroutput,"\n");
		  for (j = 0; j < 56; j++)
		  {
			  //循环左移:即用右边(编号大)的位去写左边的(编号小)的位
			  k 	 = j + totRot[i];/*static const char totRot[] = 1, 2(1+1), 4(1+1+2+2,教材上前面左移几项位数之和), 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28};*/
			  pcr[j] = pc1m[(k < (j < 28 ? 28 : 56)) ? k : k - 28];//(j < 28 ? 28 : 56):取28则左半,取56右半,k - 28表示循环移位的
			  
			  if( doEncrypt)
			  {
				  pstroutput+=sprintf(pstroutput,"%d", pc1m[(k < (j < 28 ? 28 : 56)) ? k : k - 28]); //(j < 28 ? 28 : 56):取28则左半,取56右半,k - 28表示循环移位的
				  if ((j+1)%7==0) pstroutput+=sprintf(pstroutput,"	");
				  if ((j+1)%56==0 && doEncrypt) pstroutput+=sprintf(pstroutput,"\n");
			  }
		  } /* end of for j */
		  /* Rotate left and right halves independently */
		  if (doEncrypt)pstroutput+=sprintf(pstroutput,"步骤1-2-%d-3:照以下数组进行选位并排序:\n",i);
		  for (j=0; j<48; j++)//
		  {

⌨️ 快捷键说明

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