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

📄 desf.cpp

📁 卢开澄,《计算机密码学-计算机网络中的数据保密与安全》第三版中的DES程序。在网上搜索过
💻 CPP
字号:
// DESF.cpp: implementation of the DESF class.
//
//////////////////////////////////////////////////////////////////////

#include "DESF.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////


// permuted choice table (PC1)
const static int pc1[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
};
// permuted choice key (PC2)
const static int pc2[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
};
// number left rotations of pc1 
static int ls[16] = {
	1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1
};
// initial permutation (IP)
const static int ip[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
};
// expansion operation matrix (E)
const static int e[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
};
// The (in)famous S-boxes 
const static int sbox[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
};
// 32-bit permutation function P used on the output of the S-boxes 
const static int p[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
};
// final permutation IP^-1 
const static int fp[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
};

DESF::DESF()
{

}

DESF::~DESF()
{

}

DESF::chartobits(chars ch, bits *bts)  //字符串变换成二进制
{
   int cnt1,cnt2,pos;
   for(cnt1=0;cnt1<ch.totalchar;cnt1++)
   {
	   pos=int(ch.ch[cnt1]);
	   pos=pos<0 ? pos+256 : pos;  //负数取补码
	   pos=pos+28;  //为什么+28
	   for(cnt2=7;cnt2>=0;cnt2--)
	   {
		   bts->bit[cnt1*ch.totalchar+cnt2]=(pos%2!=0) ? true:false;
		   pos/=2;
	   }
   }
   bts->totalbit=ch.totalchar*8;
}

DESF::bitstochar(bits bts, chars *ch)  //二进制变换成字符串
{
	int cnt1,cnt2,pos,power;
	for(cnt1=0;cnt1<8;cnt1++)
	{
		pos=0;
		power=128;
		for(cnt2=0;cnt2<8;cnt2++)
		{
			if(bts.bit[cnt1*8+cnt2]) pos+=power;  //数组最左边是最高位
			power/=2;
		}
		ch->ch[cnt1]=char(pos-28);
	}
	ch->totalchar=bts.totalbit/8;

}

DESF::bitmaping(int bitmapno, bits inbts, bits *outbts)  //所有需要查表的置换(无S盒)
//第二、三个参数为什么一个用普通变量,一个用变量的指针
{
	int cnt,mapsize;
	switch(bitmapno)  //确定需要置换的长度
	{
	case 1: mapsize=64 ;break;  //ip
	case 2: mapsize=64 ;break;  //fp
	case 3: mapsize=48 ;break;  //e
	case 4: mapsize=32 ;break;  //p
	case 5: mapsize=56 ;break;  //pc1
	case 6: mapsize=48 ;break;  //pc2
	}
	outbts->totalbit=mapsize;  //需要置换的的数组的位数
	for(cnt=0;cnt<mapsize;cnt++)
	{
		switch(bitmapno)  //进行查表置换
		{
		case 1: outbts->bit[cnt]=inbts.bit[ip[cnt]-1] ; break;
		case 2: outbts->bit[cnt]=inbts.bit[fp[cnt]-1] ; break;
		case 3: outbts->bit[cnt]=inbts.bit[e[cnt]-1] ; break;
		case 4: outbts->bit[cnt]=inbts.bit[p[cnt]-1] ; break;
		case 5: outbts->bit[cnt]=inbts.bit[pc1[cnt]-1] ;break;
		case 6: outbts->bit[cnt]=inbts.bit[pc2[cnt]-1] ;break;
		}
	}

}

DESF::InitIP(bits bts64, bits *Lbts32, bits *Rbts32)  //IP置换
{
	int cnt;
	bits tempbts;

	bitmaping(1,bts64,&tempbts);  //IP置换
	for(cnt=0;cnt<32;cnt++)  //将置换后的二进制分成左右两半
	{
		Lbts32->bit[cnt]=tempbts.bit[cnt];
		Rbts32->bit[cnt]=tempbts.bit[cnt+32];
	}
	Lbts32->totalbit=32;
	Rbts32->totalbit=32;

}

DESF::FinalIP(bits Lbts32, bits Rbts32, bits *bts64)
{
	int cnt;
	bits tempbts;
	for(cnt=0;cnt<32;cnt++)
	{
		tempbts.bit[cnt]=Lbts32.bit[cnt];
		tempbts.bit[cnt+32]=Rbts32.bit[cnt];
	}
	tempbts.totalbit=64;
	bitmaping(2,tempbts,bts64);

}

DESF::leftshift(bits *bit28, int times)  //密钥移位
{
	bool lastbit;
	int cnt1,cnt2;
	for(cnt1=0;cnt1<times;cnt1++)
	{
		lastbit=bit28->bit[0];  //把需要移位的数组的第一位放在lastbit
		for(cnt2=0;cnt2<bit28->totalbit-1;cnt2++)
			bit28->bit[cnt2]=bit28->bit[cnt2+1];  //原数组左移1位
		bit28->bit[bit28->totalbit-1]=lastbit;  //把左移出来的一位,也就是lastbit放如新数组的最后一位
	}

}

DESF::pc1tran(bits bts64, bits *Cbts28, bits *Dbts28)  //密钥pc1变换,并且把密钥分成左右两边
{
	int cnt;
	bits tempbts;

	bitmaping(5,bts64,&tempbts);  //pc1变换
	for(cnt=0;cnt<28;cnt++)
	{
		Cbts28->bit[cnt]=tempbts.bit[cnt];  //分成左右两边
		Dbts28->bit[cnt]=tempbts.bit[cnt+28];
	}
	Cbts28->totalbit=28;
	Dbts28->totalbit=28;

}

DESF::pc2tran(bits Cbts28, bits Dbts28, bits *Kbts48)  
{
	int cnt;
	bits tempbts;
	for(cnt=0;cnt<28;cnt++)  //将移位后的密钥左右合并
	{
		tempbts.bit[cnt]=Cbts28.bit[cnt];
		tempbts.bit[cnt+28]=Dbts28.bit[cnt];
	}
	tempbts.totalbit=56;
	bitmaping(6,tempbts,Kbts48);  //pc2变换

}

DESF::keygen(bits key, bitarray *subkey)  //生成16个子密钥
{
	bits Cbts28,Dbts28,Kbts48;
	int cnt;

	pc1tran(key,&Cbts28,&Dbts28);  //经过pc1变换后的密钥左右两边存放Cbts28、Dbts28
	for(cnt=0;cnt<16;cnt++)
	{
		leftshift(&Cbts28,ls[cnt]);  //密钥移位
		leftshift(&Dbts28,ls[cnt]);
		pc2tran(Cbts28,Dbts28,&Kbts48);  //pc2
		subkey->bitarr[cnt]=Kbts48;  //bitarr[cnt]是结构体数组
	}

}

DESF::etran(bits bts32, bits *bts48)  //e扩展
{
	bitmaping(3,bts32,bts48);

}

DESF::bitToSBoxPos(bits bts48, int boxno, int *row, int *col)  //算出S盒行列 
//为什么要先用“?”进行选择?这里也可以用pow函数
{
	* row=(bts48.bit[boxno*6]? 2:0)+(bts48.bit[boxno*6+5]? 1:0);
	* col=(bts48.bit[boxno*6+1]? 8:0)+(bts48.bit[boxno*6+2]? 4:0)+
		(bts48.bit[boxno*6+3]? 2:0)+(bts48.bit[boxno*6+4]? 1:0);
}

DESF::sboxtran(bits bts48, bits *bts32)  //S盒
{
	int cnt1,cnt2,row,col,boxout;

	for(cnt1=0;cnt1<8;cnt1++)  //8个S盒
	{
		bitToSBoxPos(bts48,cnt1,&row,&col);  //得出每个S盒子的行列
		boxout=sbox[cnt1][row*16+col];  //把(行*16+列)相当于把原来S盒的二维数组转换成一维
		for(cnt2=3;cnt2>=0;cnt2--)  //把从S盒子输出的十进制数转换为二进制
		{
			bts32->bit[cnt1*4+cnt2]=(boxout%2!=0)? true:false;
			boxout/=2;
		}
	}
	bts32->totalbit=32;

}

DESF::ptran(bits bts32, bits *fout)  //P置换
{
	bitmaping(4,bts32,fout);

}

DESF::ftran(bits inbts32, bits keyi, bits *fRes)
{
	bits bts48,bts32,xorRes48;

	etran(inbts32,&bts48);
	exclusiveOR(bts48,keyi,&xorRes48);
	sboxtran(xorRes48,&bts32);
	ptran(bts32,fRes);

}

DESF::exclusiveOR(bits bts1, bits bts2, bits *xorRes)  //扩展后的右边与密钥相异或
{
	int cnt;

	xorRes->totalbit=bts1.totalbit;
	for(cnt=0;cnt<bts1.totalbit;cnt++)
		xorRes->bit[cnt]=bts1.bit[cnt]^bts2.bit[cnt];

}

DESF::desblock(chars intext8, chars key, bool encode, chars *outtext8)  //DES加密(解密)模块
{
	int cnt,keypos;
	bits inbts,Lbts,Rbts,oldLbts;
	bits keybit,outbts,fRes;
	bitarray subkey;

	chartobits(intext8,&inbts);  //明文8个字节转换成二进制
	chartobits(key,&keybit);  //密钥8个字节转换成二进制
	keygen(keybit,&subkey);  //每轮的密钥

	InitIP(inbts,&Lbts,&Rbts);  //IP变换
	for(cnt=0;cnt<16;cnt++)  //进行16轮加密(解密)迭代
	{
		oldLbts=Lbts;
		Lbts=Rbts;
		keypos=encode ? cnt : (15-cnt);  //选择密钥
		ftran(Rbts,subkey.bitarr[keypos],&fRes);   //f函数
		exclusiveOR(oldLbts,fRes,&Rbts);  //原来的左边和经过f函数的右边相异或
	}
	FinalIP(Rbts,Lbts,&outbts);  //~IP,注意参数放的位置
	bitstochar(outbts,outtext8);

}

DESF::desEncode(char mfile[], char key[], char cfile[])  //加密,调用函数desCoding
{
	desCoding(mfile,key,cfile,true);

}

DESF::desDecode(char mfile[], char key[], char cfile[])  //解密,调用函数desCoding
{
	desCoding(mfile,key,cfile,false);

}

DESF::desCoding(char mfile[], char key[], char cfile[], bool codedir)  //将文件中字符串分成8字节一组进行加密(解密)
{
	int cnt1,cnt2;
	chars inch,inkey,outch;
	FILE * mfp;
	FILE * cfp;

	for(cnt1=0;cnt1<8;cnt1++)
		inkey.ch[cnt1]=key[cnt1];
	inkey.totalchar=8;

	if((mfp=fopen(mfile,"r"))==NULL)  //判断读入文件“mfile”是不是空
	{cout<<"Cannot open the message file"<<endl;}
	else
	{
		cfp=fopen(cfile,"w");  //新建一个文件“cfile”

		cnt1=0;
		inch.ch[cnt1]=fgetc(mfp);  //从mfp读入字符并存放数组ch[8]
		inch.totalchar=8;
		cnt2=0;
		while(!feof(mfp))  //判断文件有没有结束
		{
			cnt1++;
			cnt2++;
			inch.ch[cnt1]=fgetc(mfp);
			if(cnt1==7)
			{
				desblock(inch,inkey,codedir,&outch);
				for(cnt1=0;cnt1<8;cnt1++)  //把密文从outch中取出存放cfp
					fputc(outch.ch[cnt1],cfp);
				cnt1=-1;  //cnt1设置成-1,然后再次循环到=7
			}
		}
		cnt2=cnt2%8;  //判断明文(密文)是否正好是8字节的倍数
	    if(cnt2!=0)  //处理最后剩下不足八字节的那部分
		{
			for(cnt1=0;cnt1<(8-cnt2);cnt1++)  //不足8字节的补空格
				inch.ch[cnt1+cnt2]=' ';
		    inch.totalchar=8;
		    desblock(inch,inkey,codedir,&outch);
		    for(cnt1=0;cnt1<8;cnt1++)
				fputc(outch.ch[cnt1],cfp);
		}
	    fclose(mfp);
	    fclose(cfp);
	}

}

DESF::dispfile(char fn[])  //显示读入的文件
{
	FILE *fp;
	char ch;
	if((fp=fopen(fn,"r"))==NULL)  //判断读入文件是不是空
	{cout<<"Cannot open the file to display"<<endl;}
	else
	{
		while(!feof(fp))
		{
			ch=fgetc(fp);
			cout<<ch;
		}
		cout<<endl;
	}

}

float DESF::bitdiff(char mfile[], char cfile[], float *bitdiff8byte)
{
	FILE * mfp,* cfp;
	int ttch=0,xorRes,ttbitdiff=0;
	char mch,cch;
	float bdiff=0;

	if((mfp=fopen(mfile,"r"))==NULL)
	{cout<<"Cannot open the file to compare"<<endl;}
	if((cfp=fopen(cfile,"r"))==NULL)
	{cout<<"Cannot open the file to compare"<<endl;}
	else
	{
		while(!feof(mfp)&!feof(cfp))
		{
			ttch++;
			mch=fgetc(mfp);
			cch=fgetc(cfp);
			xorRes=mch^cch;
			ttbitdiff+=(xorRes&1)+(xorRes&2)/2+(xorRes&4)/4+(xorRes&8)/8+
				(xorRes&16)/16+(xorRes&32)/32+(xorRes&64)/64+(xorRes&128)/128;
		}
		bdiff=float(ttbitdiff)*100/float(ttch*8);
	}
	*bitdiff8byte=float(ttbitdiff)*100/float(8*8);
	return bdiff;

}

⌨️ 快捷键说明

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