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

📄 des.cpp

📁 自己编的一个DES加密解密算法代码
💻 CPP
字号:
// DES.cpp : DES算法试验
//算法注视:实现中的1个byte表示算法中的一位
//

#include "stdafx.h"


//IP、IP_1矩阵
char IP_Matrix[][8]={
	{58,50,42,34,26,18,10,2},
	{60,52,44,36,28,20,12,4},
	{62,54,46,38,30,22,14,6},
	{64,56,48,40,32,24,16,8},
	{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}
};
char IP_1_Matrix[][8]={
	{40,8,48,16,56,24,64,32},
	{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}
};

//E矩阵
char E_Matrix[][6] = {
	{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}
};

//S盒子
char S_Box[8][64] = {
	/* S1 */
	{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},

	/* S2 */
	{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},

	/* S3 */
	{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},

	/* S4 */
	{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},

	/* S5 */
	{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},

	/* S6 */
	{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},

	/* S7 */
	{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},

	/* S8 */
	{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}
};

//密码PC1矩阵
char PC1_Matrix[][7] = {
	{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}
};
//密码PC2矩阵
char PC2_Matrix[][6] = {
	{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}
};
//密码LS(循环左移)
char LS_Matrix[]={1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};

//P矩阵
char P_Matrix[] = {	
	16,  7, 20, 21,
	29, 12, 28, 17,
	 1, 15, 23, 26,
	 5, 18, 31, 10,
	 2,  8, 24, 14,
	32, 27,  3,  9,
	19, 13, 30,  6,
	22, 11,  4, 25
};

//循环左移算法
void LS(int i,char *pkey)
{
	char temp[28];
	for(int j=0;j<2;j++)
	{
		int step=LS_Matrix[i];
		int m;
		for(m=step;m<28;m++)
		{
			temp[m-step]=pkey[m+j*28];
		}
		while(step)
		{
			temp[28-step]=pkey[m-28+j*28];
			step--;
			m++;
		}
		for(int k=0;k<28;k++)
		{
			pkey[k+j*28]=temp[k];
		}
	}
	return;
}

//密码PC-1计算
void PC1(char s[],char t[])
{
	//密码格式转换
	char temp[64];
	//方案一
	/*for(int i=0;i<7;i++)
	{
		for(int j=0;j<8;j++)
		{
			temp[i*8+7-j] = (s[i] & (1 << j )) == 0 ? 0 : 1;
		}
	}
	for(int i=7;i>=0;i--)
	{
		for(int j=6;j>=0;j--)
		{
			temp[i*8+j]=temp[i*7+j];
		}
	}*/
	//方案二
	for(int i=0;i<8;i++)
	{
		for(int j=0;j<8;j++)
		{
			temp[i*8+7-j] = (s[i] & (1 << j )) == 0 ? 0 : 1;
		}
	}
	//PC1
	for(int i=0;i<8;i++)
	{
		for(int j=0;j<7;j++)
		{
			int foo=PC1_Matrix[i][j]-1;
			t[i*7+j]=temp[foo];
		}
	}
	return;
}

//产生每代密码子
void genKey(char key[],int i,char *keys)
{
	LS(i,key);
	//PC2转换
	for(int i=0;i<8;i++)
	{
		for(int j=0;j<6;j++)
		{
			int lo=PC2_Matrix[i][j]-1;
			keys[i*6+j]=key[lo];
		}
	}
}


//做IP和IP_1转换
//参数:8*8byte数据的指针
//返回:直接在原数据上修改
void IP(char m[][8])
{
	char temp[8][8];
	for(int i=0;i<8;i++)
	{
		for(int j=0;j<8;j++)
		{
			int lo=IP_Matrix[i][j]-1;
			temp[i][j]=m[lo/8][lo%8];
		}
	}
	for(int i=0;i<8;i++)
	{
		for(int j=0;j<8;j++)
		{
			m[i][j]=temp[i][j];
		}
	}
	return ;
}

//IP_1运算
void IP_1(char *pchar)
{
	char temp[64];
	for(int i=0;i<8;i++)
		for(int j=0;j<8;j++)
		{
			temp[i*8+j]=pchar[IP_1_Matrix[i][j]-1];
		}
	for(int i=0;i<64;i++)
		pchar[i]=temp[i];
}

//做E转换
//输入32byte数据s,放到48byte数据的目标t中
void E(char *s,char *t)
{
	for(int i=0;i<8;i++)
	{
		for(int j=0;j<6;j++)
		{
			t[i*6+j]=s[E_Matrix[i][j]-1];
		}
	}
}


//将输入的16个char数据转换成64byte
void convertM(const char s[],char t[][8])
{
	for(int i=0;i<8;i++)
	{
		for(int j=0;j<8;j++)
		{
			t[i][7-j] = (s[i] & (1 << j )) == 0 ? 0 : 1;
		}
	}
	return;
}

//打印中间计算结果
void cc(char aa[8],char rr[])
{
	rr[0]=(aa[0]<<3)+(aa[1]<<2)+(aa[2]<<1)+aa[3]+0x30;
	if(rr[0]>0x39)rr[0]+=7;
	rr[1]=(aa[4]<<3)+(aa[5]<<2)+(aa[6]<<1)+aa[7]+0x30;
	if(rr[1]>0x39)rr[1]+=7;
	return;
}

void printMatrix(char * step,char m[][8])
{
	char foo[2];
	printf("Now Step: %s End,Results are \n",step);
	for(int i=0;i<8;i++)
	{
		for(int j=0;j<8;j++)
		{
			printf("%d ",m[i][j]);
		}
		cc(m[i],foo);
		printf("\t%c %c\n",foo[0],foo[1]);
	}
	return;
}
//打印密码
void printKey(char keys[][48])
{
	for(int i=0;i<16;i++)
	{
		printf("\tKey(%d): ",i+1);
		for(int m=0;m<6;m++)
		{
			for(int j=0;j<8;j++)
				printf("%d",keys[i][m*8+j]);
			printf(" ");
		}
		printf("\n");
	}
	return;
}
//打印CD
void printCD(int i,char *key)
{
	printf("C(%2d): ",i);
	for(int m=0;m<28;m++)
		printf("%d",key[m]);
	printf("\t");
	printf("D(%2d): ",i);
	for(int m=28;m<56;m++)
		printf("%d",key[m]);
	printf("\n");
	return;
}
//打印中间步骤
void printMid(char * ss,char* s,int len)
{
	printf("\tAfter %s\t",ss);
	for(int i=0;i<len/4;i++)
	{
		for(int j=0;j<4;j++)
		{
			printf("%d",s[i*4+j]);
		}
		printf(" ");
	}
	printf("\n");
}


//算法核心函数f
void f(char* R,char* key)
{
	char temp48[48],temp32[32];
	//对L做E转换,成48bit
	E(R,temp48);
	printMid("E",temp48,48);
	
	//temp与key做+运算
	for(int i=0;i<48;i++)
	{
		temp48[i]=temp48[i]^key[i];
	}
	printMid("E+k",temp48,48);


	//S转换
	for(int i=0;i<8;i++)
	{
		int row=0,vol=0,temp=0;
		row=temp48[i*6+0]*2+temp48[i*6+5];
		vol=temp48[i*6+1]*8+temp48[i*6+2]*4+temp48[i*6+3]*2+temp48[i*6+4];
		temp=S_Box[i][row*16+vol];
		for(int j=0;j<4;j++)
		{
			temp32[i*4+j]=(temp&(1<<(3-j)))==0?0:1;
		}
	}
	printMid("S",temp32,32);

	//P转换
	for(int i=0;i<32;i++)
	{
		R[i]=temp32[P_Matrix[i]-1];
	}
}

//每一轮函数
void roll(char *L,char *R,char *key)
{
	char temp[32]={};
	for(int i=0;i<32;i++)
		temp[i]=R[i];
	f(R,key);
	printMid("f()",R,32);
	//R=L+f;
	for(int i=0;i<32;i++)
	{
		R[i]=L[i]^R[i];
	}
	printMid("R=L^R",R,32);
	//L=R;
	for(int i=0;i<32;i++)
		L[i]=temp[i];
	printMid("L=R",L,32);
	return;
}

int _tmain(int argc, _TCHAR* argv[])
{
	int foo;
	char m[8][8];//用于计算的64byte数据
	char inputM[9] = "computer";//输入的8个char表示
	char c[8][8];//64byte密文
	char outputC[9];//用于输出的64bit密码的字符串表示

	char inputK[9]="security";//密码
	char key[48];//参与计算的密码中间数
	char keys[16][48];//保留的密码子



	//密码PC1计算
	PC1(inputK,key);
	printCD(0,key);
	
	//经过16轮计算产生16个密码子
	for(int i=0;i<16;i++)
	{
		genKey(key,i,keys[i]);
		printCD(i+1,key);
	}
	printKey(keys);


//加密
	printf("Start Encoding\n");
	//转换数据,便于计算
	convertM(inputM,m);
	printMatrix("Input",m);
	
	//做IP运算
	IP(m);
	printMatrix("After IP",m);

	//开始做16轮循环
	for(int i=0;i<16;i++)
	{
		roll(&m[0][0],&m[4][0],keys[i]);
		char s[3];
		sprintf(s,"%d",i+1);
		printMatrix(s,m);
	}
	//处理最后多余的一次左右转换
	char temp[32]={};
	char *L=&m[0][0],*R=&m[4][0];
	for(int i=0;i<32;i++)
	{
		temp[i]=L[i];
		L[i]=R[i];
		R[i]=temp[i];
	}
	IP_1(&m[0][0]);
	printMatrix("End of Encoding",m);

//解密
	puts("Start Decoding");
	IP(m);
	for(int i=15;i>=0;i--)
		roll(&m[0][0],&m[4][0],keys[i]);
	for(int i=0;i<32;i++)
	{
		temp[i]=L[i];
		L[i]=R[i];
		R[i]=temp[i];
	}
	IP_1(&m[0][0]);
	printMatrix("End of Decoding",m);





	scanf("%d",&foo);

	return 0;
}

⌨️ 快捷键说明

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