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

📄 des.cpp

📁 自己编写的DES加密/解密完整源程序, Windows界面.是用VC6MFC编写的.包括ECB和CBC两种模式.
💻 CPP
字号:
// DES.cpp: implementation of the DES class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "DES.h"
#include "iostream.h"
#include "memory.h"
#include "stdlib.h"
#include "fstream.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

DES::DES()
{

}

DES::~DES()
{

}

//*************************变量初始化部分****************************

int DES::ENCRYPT=0;	//加密
int DES::DECRYPT=1;	//解密
bool DES::subKeys[16][48];

//置换选择1矩阵
int DES::PC1matrix[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
};
//记录每一轮左循环移位位数的数组
int DES::rLmatrix[16]={1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};
//置换选择2矩阵
int DES::PC2matrix[48]={
	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
};
//选择扩展运算E矩阵
int DES::Ematrix[48]={
	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 DES::sBox[8][4][16]={
	14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7,		//S1
	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,

	15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10,		//S2
	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,

	10,0,9,14,6,3,15,5,1,13,12,7,1,4,2,8,		//S3
	13,7,0,9,3,4,6,1,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,

	7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15,		//S4
	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,

	2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9,		//S5
	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,

	12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11,		//S6
	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,

	4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1,		//S7
	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,

	13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7,		//S8
	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
};
//置换(P)运算矩阵
int DES::Pmatrix[32]={
	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
};
//初始置换矩阵
int DES::IPmatrix[64]={
	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
};
//逆初始置换矩阵
int DES::rvsIPmatrix[64]={
	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
};

//****************************产生子密钥部分***************************

//置换选择1
//根据输入的64位和PC1,选择56位做为初始密钥
void DES::PC1(bool in[64],bool out[56])
{
	for(int i=0;i<56;i++)
		out[i]=in[PC1matrix[i]-1];
}

//循环左移位
//输入轮数和56位,对左28位和右28位分别循环左移位,结果仍放在in[56]
void DES::rotateL(int loop,bool in[56])
{
	bool temp[56];
	memcpy(temp,in,56);
	int l=rLmatrix[loop-1];
	//操作左28位
	memcpy(in,temp+l,28-l);
	memcpy(in+28-l,temp,l);
	//操作右28位
	memcpy(in+28,temp+28+l,28-l);
	memcpy(in+56-l,temp+28,l);
}

//置换选择2
//输入移位后的56位,置换选择结果(子密钥)放在out[48]
void DES::PC2(bool in[56],bool out[48])
{
	for(int i=0;i<48;i++)
		out[i]=in[PC2matrix[i]-1];
}

//产生子密钥的函数
//调用了本部分上面的几个函数,结果放在subKeys[16][48]
void DES::getSubKeys(char key[8])
{
	bool binKey[64];
	txt2Bin(key,binKey,8);

	bool afterPC1[56];
	PC1(binKey,afterPC1);

	for(int i=1;i<=16;i++)
	{
		rotateL(i,afterPC1);
		PC2(afterPC1,subKeys[i-1]);
	}
}

//**************************F函数部分*******************************
//选择扩展运算E
//将32位扩展成48位,输入in[32]是右32位,结果放在out[48]
void DES::expand(bool in[32],bool out[48])
{
	for(int i=0;i<48;i++)
		out[i]=in[Ematrix[i]-1];
}

//异或运算
//将扩展运算后48位与轮密钥异或.结果仍放在in1_out[48]
void DES::XOR(bool in1_out[],bool in2[],int length)
{
	bool * temp=new bool[length];
	memcpy(temp,in1_out,length);
	for(int i=0;i<length;i++)
		in1_out[i]=temp[i]^in2[i];
	delete []temp;
}

//S盒运算.
//48位变为32位
void DES::sBoxF(bool in[48],bool out[32])
{
	int si,line,col;	//分别是盒号,行号,列号
	char tmp;			//盒中的元素
	int k=0;			//控制out数组中当前存放位置

	for(int i=0;i<48;i+=6)	//每六位对应一个S盒
	{
		si=i/6;
		line=in[i]*2+in[i+5]*1;
		col=in[i+1]*8+in[i+2]*4+in[i+3]*2+in[i+4]*1;
		tmp=sBox[si][line][col];
		for(int j=3;j>=0;j--)
		{
			out[k*4+j]=(tmp & 0x1)?1:0;
			tmp>>=1;
		}
		k++;
	}
}

//置换(P)运算
//这是F函数的最后一步,结果仍放在in[32]
void DES::PF(bool in[32])
{
	bool temp[32];
	memcpy(temp,in,32);
	for(int i=0;i<32;i++)
		in[i]=temp[Pmatrix[i]-1];
}

//F函数
//输入右32位和本轮子密钥,输出32位.调用了本部分上面的几个函数。
void DES::desF(bool in[32],bool subKey[48],bool out[32])
{
	bool afterE[48];
	expand(in,afterE);	//扩展运算
	XOR(afterE,subKey,48);	//异或运算
	bool afterSBox[32];
	sBoxF(afterE,afterSBox);	//S盒运算
	PF(afterSBox);	//置换运算
	memcpy(out,afterSBox,32);
}

//*************************轮加密部分******************************
//轮加密函数
//调用了F函数部分.结果仍放在inL[32],inR[32]
void DES::round(bool inL[32],bool inR[32],bool subKey[48])
{
	bool temp[32];
	memcpy(temp,inL,32);	//暂存左32位
	memcpy(inL,inR,32);		//下一轮的左32位

	bool fout[32];
	desF(inR,subKey,fout);	//调用F函数
	XOR(temp,fout,32);		//异或运算
	memcpy(inR,temp,32);	//下一轮的右32位
}


//*************************单组加密/解密部分*****************************
//文本与二进制转换函数
//将8个字符转换成"二进制"out[64],实际上bool值在内存中占用一个字节
void DES::txt2Bin(char in[],bool out[],int count)
{
	for(int i=0;i<count;i++)
	{
		char ch=in[i];
		for(int k=7;k>=0;k--)
		{
			out[i*8+k]=(ch & 0x1)?1:0;
			ch>>=1;
		}
	}

	return ;
}

//初始置换
//对64bit进行初始置换,结果仍放在in[64]
void DES::IP(bool in[64])
{
	bool temp[64];
	memcpy(temp,in,64);
	for(int i=0;i<64;i++)
		in[i]=temp[IPmatrix[i]-1];
}


//左右交换
//16轮后的左32位与右32位交换,结果仍放在in[64]
void DES::exchange(bool in[64])
{
	bool temp[64];
	memcpy(temp,in,64);
	memcpy(in,temp+32,32);
	memcpy(in+32,temp,32);
}

//逆初始置换
//将左右交换后的64位进行逆初始置换,结果仍放在in[64]
void DES::rvsIP(bool in[64])
{
	bool temp[64];
	memcpy(temp,in,64);
	for(int i=0;i<64;i++)
		in[i]=temp[rvsIPmatrix[i]-1];
}

//二进制与文本转换函数,与本部分上面的txt2Bin作用相反
//将64位二进制转换成字符out[8]
void DES::bin2Txt(bool in[],char out[],long int count)
{
	int i,j,m=7,k=0;
	char temp=NULL;
	for(i=0;i<count;i+=8)
	{
		for(j=i;j<i+8;j++)
			temp=temp|(in[j]<<m--);
		out[k++]=temp;
		m=7;temp=NULL;
	}
}

//单组加密/解密函数,调用了本部分函数及轮加密函数
//输入枚举参数operate表示加密还是解密,结果放在out[8]
void DES::desGroup(char in[8],char out[8],int operate)
{
	bool temp[64];
	txt2Bin(in,temp,8);	//单组转换为二进制
	desGroupBin(temp,operate);
	bin2Txt(temp,out,64);
}

//单组加密/解密函数
//与上面desGroup()的区别是对"二进制"进行操作
void DES::desGroupBin(bool in_out[64],int operate)
{
	IP(in_out);				//初始置换
	if(operate==0)
		for(int i=1;i<=16;i++)	//16轮加密运算
			round(in_out,in_out+32,subKeys[i-1]);
	else if(operate==1)
		for(int i=1;i<=16;i++)	//16轮解密运算
			round(in_out,in_out+32,subKeys[16-i]);
	exchange(in_out);			//左右交换
	rvsIP(in_out);			//逆初始置换
}

//*****************************ECB模式**********************************
//ECB模式加密/解密函数
//operate选择是加密还是解密,length是输入串的长度(发生变化)
void DES::desECB(char *in,char *out,int length,int operate)
{
	char temp[8];int i;
	if(operate==DES::ENCRYPT)
		for(i=0;i<length;i+=8)
		{
			memcpy(temp,in+i,8);
			DES::desGroup(temp,out+i,DES::ENCRYPT);
		}
	else if(operate==DES::DECRYPT)
		for(i=0;i<length;i+=8)
		{
			memcpy(temp,in+i,8);
			DES::desGroup(temp,out+i,DES::DECRYPT);
		}
}

//*******************************CBC模式*********************************
//CBC模式加密/解密函数
void DES::desCBC(char *in,char *out,char *iv,int length,int operate)
{
	char temp[8];int i;
	if(operate==DES::ENCRYPT)
		for(i=0;i<length;i+=8)
		{
			memcpy(temp,in+i,8);
			if(i==0)
				XORch(temp,iv,8);
			else
				XORch(temp,out+i-8,8);
			DES::desGroup(temp,out+i,DES::ENCRYPT);
		}
	else if(operate==DES::DECRYPT)
		for(i=0;i<length;i+=8)
		{
			memcpy(temp,in+i,8);
			DES::desGroup(temp,out+i,DES::DECRYPT);
			if(i==0)
				XORch(out,iv,8);
			else
				XORch(out+i,in+i-8,8);
		}
}

//字符数组异或
//结果放在in1_out[]
void DES::XORch(char in1_out[],char in2[],int length)
{
	for(int i=0;i<length;i++)
		in1_out[i]=in1_out[i]^in2[i];
}

//*********************************CFB模式***********************************
//CFB模式加密/解密函数
void DES::desCFB(char *in,char *out,char *iv,int length,int operate,int width)
{
	bool sreg[64];
	txt2Bin(iv,sreg,8);

	long int newlen=length*8;
	if(newlen%width!=0) newlen+=width-newlen%width;
	bool *temp=new bool[newlen];
	memset(temp,0,newlen);
	txt2Bin(in,temp,length);
	if(operate==DES::ENCRYPT)
	{
		for(int i=0;i<newlen;i+=width)
		{
			if(i>0)
				shiftL(sreg,temp+i-width,width);
			desGroupBin(sreg,DES::ENCRYPT);
			XOR(temp+i,sreg,width);
		}
	}
	else if(operate==DES::DECRYPT){
		bool *savewidth=new bool[width];
		for(int j=0;j<newlen;j+=width)
		{
			if(j>0)
				shiftL(sreg,savewidth,width);
			desGroupBin(sreg,DES::ENCRYPT);
			memcpy(savewidth,temp+j,width);
			XOR(temp+j,sreg,width);
		}
		delete []savewidth;
	}

	bin2Txt(temp,out,newlen);
	delete []temp;

}

//左移位函数
//左移count位,并将in2的count位放在右面
void DES::shiftL(bool in1_out[64],bool in2[],int count)
{
	memcpy(in1_out,in1_out+count,64-count);
	memcpy(in1_out+64-count,in2,count);
}


//********************************OFB模式*************************
//OFB模式加密/解密函数
void DES::desOFB(char *in,char *out,char *iv,int length,int width)
{
	bool sreg[64];
	txt2Bin(iv,sreg,8);

	long int newlen=length*8;
	if(newlen%width!=0) newlen+=width-newlen%width;
	bool *temp=new bool[newlen];
	memset(temp,0,newlen);
	txt2Bin(in,temp,length);

	bool *savewidth=new bool[width];
	for(int i=0;i<newlen;i+=width)
	{
		if(i>0)
			shiftL(sreg,savewidth,width);
		desGroupBin(sreg,DES::ENCRYPT);
		memcpy(savewidth,sreg,width);
		XOR(temp+i,sreg,width);
	}
	bin2Txt(temp,out,newlen);

	delete []savewidth;
	delete []temp;

}

⌨️ 快捷键说明

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