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

📄 des.h

📁 DES对称密钥加密算法,基于最基本的电码本模式.
💻 H
📖 第 1 页 / 共 2 页
字号:
{//二进制显示字节
	for(int i=0;i<8;i++)
		printf("%d",GetBitFromSingleByte(uData,8-i));
	printf("\n");
}

UCHAR GetBit(UCHAR uData[],UCHAR uBytes,UCHAR uBit)
{//uData为输入的字节型数组,uBytes为输入数组的字节数,uBit表示第几位(*从1开始),返回该位的值
	UCHAR m,n;
	if(uBit<1 || uBit>8*uBytes)
		return ERROR_BITOUTOFRANGE;	//有效性检查
	if(uBit%8==0)
	{//处理该位为每字节的最高位,其模8为0的特殊情况
		m=uBit/8-1;//该位所在的字节
		n=7;//该位所在字节中的位数
	}
	else
	{
		m=uBit/8;//该位所在的字节
		n=uBit%8-1;//该位所在字节中的位数
	}
	if(uData[m] & (1<<n))//判断该位的值
		return 1;
	else
		return 0;
}
UCHAR GetBitFromSingleByte(UCHAR uData,UCHAR uBit)
{//单字节版
	UCHAR n;
	if(uBit<1 || uBit>8)
		return ERROR_BITOUTOFRANGE;
	n=uBit-1;
	if(uData & (1<<n))
		return 1;
	else
		return 0;
}
UCHAR SetBit(UCHAR uData[],UCHAR uBytes,UCHAR uBit,UCHAR uValue)
{//设置一个数组某位的值,索引从1开始,uData为目标数组,uByte为数组字节数,uValue为设置的值
	UCHAR m,n;
	if(uBit<1 || uBit>8*uBytes)
		return ERROR_BITOUTOFRANGE;
	if(uBit%8==0)
	{//处理该位为每字节的最高位,其模8为0的特殊情况
		m=uBit/8-1;
		n=7;
	}
	else
	{
		m=uBit/8;
		n=uBit%8-1;
	}
	if(uValue)
		uData[m]|=(1<<n);//如果uValut非0,置位该位
	else
		uData[m]&=(~(1<<n));//否则该位清0
	return ERROR_SUCCESSED;
}
UCHAR SetBitOfSingleByte(UCHAR *uData,UCHAR uBit,UCHAR uValue)
{//置位单字节版
	UCHAR n;
	if(uBit<1 || uBit>8)
		return ERROR_BITOUTOFRANGE;
	n=uBit-1;
	if(uValue)
		*uData|=(1<<n);
	else
		*uData &=(~(1<<n));
	return ERROR_SUCCESSED;
}
UCHAR PermuteSelectKey1(UCHAR uIn[],UCHAR uOut[])
{//密钥初始置换选择1,输入64位,有效输出56位,但输出还是8个字节,每4个字节高4位置0
	UCHAR uIndex=1;
	memset(uOut,0,8);//uOut数组的规模应该与PC_1表规模一致,清0
	for(UCHAR i=0;i<8;i++)
		for(UCHAR j=0;j<7;j++)
		{//遍历PC_1表,填充uOut数组
			if((i==3||i==7) && j==6)
			{//如果到达第28或者第56个比特,先根据PC_1表中的值读输入数组中的指定位,用其值
			 //赋予当前位,然后再填充4个0
				SetBit(uOut,8,uIndex++,GetBit(uIn,8,PC_1[i][j]));
				for(UCHAR k=0;k<4;k++)
					SetBit(uOut,8,uIndex++,0);				
			}
			else//否则只赋值
				SetBit(uOut,8,uIndex++,GetBit(uIn,8,PC_1[i][j]));
		}
	return ERROR_SUCCESSED;
}
UCHAR CycleLeftShift(UCHAR uData[],UCHAR uIndex)
{//根据轮数uIndex和uLeftShiftCount表对uData数组进行循环左移
	UCHAR uCount=uLeftShiftCount[uIndex-1];//读移位位数
	UCHAR uLeftOverflowBits;//左溢出的位
	uData[3]=uData[3]<<uCount;//最高字节左移uCount位
	uLeftOverflowBits=(uData[3] & 0xF0)>>4;//取高4位保存待最后放至数尾
	uData[3]&=0x0F;//清最高字节高4位
	for(UCHAR i=2;i>=0 && i<=2;i--) //加上&&符号防止计数器溢出
	{
		UCHAR uBuff=uData[i];//保存字节
		uData[i]=(UCHAR)(uData[i]<<uCount);//左移uCount位
		for(UCHAR j=7;j>7-uCount;j--)
		{//用本字节左移溢出的高位填充高一字节左移后的低位
			SetBitOfSingleByte(&uData[i+1],j+uCount-7,GetBitFromSingleByte(uBuff,j+1));
		}
	}
	uData[0]|=uLeftOverflowBits;//最低位填充最高字节左移溢出的位
	return ERROR_SUCCESSED;
}
void SubkeyfCycleLeftShift(UCHAR uLeft[],UCHAR uRight[],UCHAR uIndex)
{//子密钥左右两部分循环左移
	CycleLeftShift(uLeft,uIndex);
	CycleLeftShift(uRight,uIndex);
}
UCHAR PermuteSelectKey2(UCHAR uIn[],UCHAR uOut[])
{//uIn为输入的64bit数,其中有56bit位有效数据,每4个字节的高4位空0,先调整使之紧凑,
 //变成56bit数7个字节,然后再查表进行置换选择2,输出uOut为48bit
	
	UCHAR LowHalfByte;
	LowHalfByte=uIn[4] & 0x0F;//获得输入第5个字节的低4位
	uIn[3]|=(LowHalfByte<<4);//移入第4个字节高4位,低4字节除了第4个字节需要处理外其他不用处理
	for(UCHAR i=5;i<8;i++)
	{//处理高4字节
		LowHalfByte=uIn[i] & 0x0F; //获得本字节低4bit
		uIn[i-1]=uIn[i-1]>>4; //低一字节右移动4位
		uIn[i-1]|=(LowHalfByte<<4);//填充低一字节的高4位
	}
	uIn[7]^=uIn[7];//最高字节清0
//====以上是去掉多余0的代码,以下是置换选择2的代码====//
	UCHAR uIndex=1;	
	memset(uOut,0,6);
	for(UCHAR j=0;j<6;j++)
		for(UCHAR k=0;k<8;k++)
			SetBit(uOut,6,uIndex++,GetBit(uIn,7,PC_2[j][k]));	
	return ERROR_SUCCESSED;
}
UCHAR ExtendPermute(UCHAR uIn[],UCHAR uOut[])
{//32bit明文的扩展置换,使用E盒
	UCHAR uIndex=1;	
	memset(uOut,0,6);
	for(UCHAR i=0;i<8;i++)
		for(UCHAR j=0;j<6;j++)
			SetBit(uOut,6,uIndex++,GetBit(uIn,4,E_BOX[i][j]));	
	return ERROR_SUCCESSED;
}
void XorBytes(UCHAR uPlainText[],UCHAR uSubKey[],UCHAR uBits)
{//数组异或,输出仍存在第一个参数中
	for(UCHAR i=0;i<uBits;i++)
		uPlainText[i]^=uSubKey[i];
}
UCHAR SubstituteSelect(UCHAR uIn[],UCHAR uOut[])
{//用S盒进行代换选择,输入48位,输出32位
	UCHAR uBit=0,uTemp1=0,uTemp2=0,uRow=0,uColumn=0,uValue=0;
    memset(uOut,0,4);//输出清0
	for(UCHAR i=1;i<=48;i++)
	{//遍历输入的48位
		uBit=GetBit(uIn,6,i);//获得输入第i位值
		if((i-1)%6==0)
		{//如果是每6bit的开始
			uTemp1=uBit;//保存当前位值做行值的低位
		}
		else if(i%6==0)
		{//如果是每6bit的结束
			uRow=(uBit<<1)|uTemp1;//当前位为行值的高位,左移一位或低位得行值
			uValue=S_BOX[i/6-1][uRow][uColumn];//根据i可得S盒表的序号i/6-1,并根据行列值求S盒值
			if(i%12==0)			
			{//如果是每12bit的结束
				uOut[i/12-1]|=(uValue<<4);//uValue为输出每字节的高4位,故左移4位或低4位	
			}
			else//如果不是12bit的结束
				uOut[(i/6-1)/2]|=uValue;//uValue为输出每字节的低4位,保存的当前字节中
			uTemp1=0;//中间变量清0
	    	uTemp2=0;
			uValue=0;
			uRow=0;
			uColumn=0;
		}
		else
		{//如果是列值中的位
			uColumn=(uBit<<(i%6-2))|uTemp2;//当前位左移i%6-2位后与上一位列值按位或得当前位列值
			uTemp2=uColumn;//uTemp2存放遍历到上一位时的列值
		}
	}
	return ERROR_SUCCESSED;
}
UCHAR Permute(UCHAR uData[])
{//对S盒输出进行置换,用P盒
	UCHAR uIndex=1;
	UCHAR uBuff[4];
	memcpy(uBuff,uData,4);
	for(UCHAR i=0;i<4;i++)
		for(UCHAR j=0;j<8;j++)
			SetBit(uData,4,uIndex++,GetBit(uBuff,4,P_BOX[i][j]));
	return ERROR_SUCCESSED;
}
UCHAR GenerateSubkey(UCHAR uIn[],UCHAR uOut[][6])
{//生成子密钥表
	UCHAR uSubkeyOut[6]={0},uTemp[8]={0};
	memset(uOut,0,16*6);
	//密钥置换选择1,输入uIn为64位,输出uTemp的56位有效,总64位,分左右32位,每32位高4位空0。
	PermuteSelectKey1(uIn,uTemp);
	for(UCHAR i=0;i<16;i++)
	{
		SubkeyfCycleLeftShift(uTemp,uTemp+4,i+1);//循环左移
		PermuteSelectKey2(uTemp,uSubkeyOut);//置换紧缩56位(其实为64位)变48位子密钥
		memcpy(uOut[i],uSubkeyOut,6);//保存至输出数组中
	}
	return ERROR_SUCCESSED;
}
UCHAR F_Function(UCHAR uRight[],UCHAR uSubkey[])
{//轮函数,输入为明文右32位和48位子密钥,输出为32位,仍存在uRight中
	UCHAR uExtended[6];
	memset(uExtended,0,6);
	ExtendPermute(uRight,uExtended);//32位明文扩展置换,生成48位数
	XorBytes(uExtended,uSubkey,6);//与48位子密钥异或
	SubstituteSelect(uExtended,uRight);//用S盒代换选择48位数,输出32位数
	Permute(uRight);//置换32位数,输出在uRight中
	return ERROR_SUCCESSED;
}
UCHAR PlainTextPermute(UCHAR uData[],UCHAR uTable[][8])
{//明文初始置换和逆初始置换
	UCHAR uIndex=1;
	UCHAR uBuff[8];
	memcpy(uBuff,uData,8);
	for(UCHAR i=0;i<8;i++)
		for(UCHAR j=0;j<8;j++)
			SetBit(uData,8,uIndex++,GetBit(uBuff,8,uTable[i][j]));
	return ERROR_SUCCESSED;
}


#endif

⌨️ 快捷键说明

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