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

📄 sdesimpl.cpp

📁 S-DES加密算法输入为一个8位的明文组和一个10位的密钥
💻 CPP
字号:
// SDESImpl.cpp: implementation of the SDESImpl class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "SDES.h"
#include "SDESImpl.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

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

SDESImpl::SDESImpl()
{

}

SDESImpl::~SDESImpl()
{

}
// initial permutation IP
const static char IP_Table[8] = {
	2, 6, 3, 1, 4, 8, 5,7
};
// final permutation IP^-1 
const static char IPR_Table[8] = {
	4, 1, 3, 5, 7, 2, 8, 6
};
// expansion operation matrix  //扩张和置换后得到2*4的矩阵
static const char E_Table[8] = {
	4,  1,  2,  3, 
	2,  3, 	 4,  1
};
// 4-bit permutation function P used on the output of the S-boxes 
const static char P_Table[4] = {
	2, 4, 3, 1
};
// permuted choice table (key) 
const static char PC1_Table[10] = {
	3, 5, 2, 7, 4, 10,  1,  9, 8, 6
};
// permuted choice key (table) 
const static char PC2_Table[8] = {
	6, 3, 7, 4,  8,  5,  10,9 
};
// number left rotations of pc1 
const static char LOOP_Table[2] = {
	1,2
};
// The (in)famous S-boxes 
const static char S_Box[2][4][4] = {
	// S1 
	1,	 0,	3,	 2, 
	3, 2, 1,  0, 
	0, 2,  1, 3,  
	3,  1,  3, 2,

	
	// S2 
	0,	 1,	2,	 3, 
	2, 0, 1,  3, 
	3, 0,  1, 0,  
	2,  1,  0, 3

};

//////////////////////////////////////////////////////////////////////////

typedef bool    (*PSubKey)[2][8];//PSubKey为指向subKey[16][48]的指针//
//static bool SubKey[2][16][48];// 16圈子密钥

//////////////////////////////////////////////////////////////////////////

static void SDES(char Out[1], char In[1], const PSubKey pSubKey, bool Type);//标准DES加/解密
static void SetKey(const char* Key, int len);// 设置密钥
static void SetSubKey(PSubKey pSubKey, const char Key[2]);// 设置子密钥
static void F_func(bool In[4], const bool Ki[8]);// f 函数
static void S_func(bool Out[4], const bool In[8]);// S 盒代替
static void Transform(bool *Out, bool *In, const char *Table, int len);// 变换
static void Xor(bool *InA, const bool *InB, int len);// 异或
static void RotateL(bool *In, int len, int loop);// 循环左移
static void ByteToBit(bool *Out, const char *In, int bits);// 字节组转换成位组
static void BitToByte(char *Out, const bool *In, int bits);// 位组转换成字节组

//////////////////////////////////////////////////////////////////////////

static bool SubKey[2][2][8];// 16圈子密钥
static bool Is3DES;// 3次DES标志
static char Tmp[256], deskey[4];

//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////
// Code starts from Line 130
//////////////////////////////////////////////////////////////////////////

void SetKey(const char* Key, int len)
{
	memset(deskey, 0, 4);
	memcpy(deskey, Key, len>4?4:len);
	SetSubKey(&SubKey[0], &deskey[0]);
	Is3DES = len>2 ? (SetSubKey(&SubKey[1], &deskey[2]), true) : false;
    //如果密钥长度大于8个字节,就后面的16组48位的子密钥生成存放在SubKey[1],前面生成的已经放在SubKey[0]
}
void SDES(char  Out[1], char In[1], const PSubKey pSubKey, bool Type)
{
    static bool M[8], tmp[4], *Li=&M[0], *Ri=&M[4];
    ByteToBit(M, In, 8);
    Transform(M, M, IP_Table, 8);
    if( Type == ENCRYPT ){
        for(int i=0; i<2; ++i) {
            memcpy(tmp, Ri, 4);
            F_func(Ri, (*pSubKey)[i]);
            Xor(Ri, Li, 4);
            memcpy(Li, tmp, 4);
        }
    }else{
        for(int i=1; i>=0; --i) {
            memcpy(tmp, Li, 4);
            F_func(Li, (*pSubKey)[i]);
            Xor(Li, Ri, 4);
            memcpy(Ri, tmp, 4);
        }
	}
    Transform(M, M, IPR_Table, 8);
    BitToByte(Out, M, 8);
}
void SetSubKey(PSubKey pSubKey, const char Key[2])//用密钥Key(2*8=16位,但取前5*2=10位)生成2组子密钥,放在(*pSubKey)[i],每组48位
{
    static bool K[16], *KL=&K[0], *KR=&K[5];
    ByteToBit(K, Key, 16);
    Transform(K, K, PC1_Table, 10);
    for(int i=0; i<2; ++i) {
        RotateL(KL, 5, LOOP_Table[i]);
        RotateL(KR, 5, LOOP_Table[i]);
        Transform((*pSubKey)[i], K, PC2_Table, 8);
    }
}
void F_func(bool In[4], const bool Ki[8])
{
    static bool MR[8];
    Transform(MR, In, E_Table, 8);//由4位扩大为8位
    Xor(MR, Ki, 8);
    S_func(In, MR);
    Transform(In, In, P_Table, 4);
}
void S_func(bool Out[4], const bool In[8])
{
    for(char i=0,j,k; i<2; ++i,In+=4,Out+=2) {
        j = (In[0]<<1) + In[3];//化为十进制
        k = (In[1]<<1) + In[2];//化为十进制
		ByteToBit(Out, &S_Box[i][j][k], 2);//2 bits * 2 = 4 bits
    }
}
void Transform(bool *Out, bool *In, const char *Table, int len)
{
    for(int i=0; i<len; ++i)
        Tmp[i] = In[ Table[i]-1 ];
    memcpy(Out, Tmp, len);
}
void Xor(bool *InA, const bool *InB, int len)
{
    for(int i=0; i<len; ++i)
        InA[i] ^= InB[i];
}
void RotateL(bool *In, int len, int loop)
{
    memcpy(Tmp, In, loop);
    memcpy(In, In+loop, len-loop);
    memcpy(In+len-loop, Tmp, loop);
}
void ByteToBit(bool *Out, const char *In, int bits)
{
    for(int i=0; i<bits; ++i)
        Out[i] = (In[i>>3]>>(i&7)) & 1;
}
void BitToByte(char *Out, const bool *In, int bits)
{
    memset(Out, 0, bits>>3);
    for(int i=0; i<bits; ++i)
        Out[i>>3] |= In[i]<<(i&7);
}


bool SDESImpl::SDESer(char * Out,char * In,long datalen,const char*Key,int keylen,bool Type)
{
	if( !( Out && In && Key && (datalen=(datalen+7)&0xfffffff8) ) ) 
			return false;
		SetKey(Key, keylen);
		if( !Is3DES ) {   // 1次DES
			for(long i=0,j=datalen; i<j; ++i,Out+=1,In+=1)
				SDES(Out, In, &SubKey[0], Type);//每次加密8位,总共要datalen次
		} else{   // 3次DES 加密:加(key0)-解(key1)-加(key0) 解密::解(key0)-加(key1)-解(key0)
			for(long i=0,j=datalen; i<j; ++i,Out+=1,In+=1) {
				SDES(Out, In,  &SubKey[0], Type);
				SDES(Out, Out, &SubKey[1], !Type);
				SDES(Out, Out, &SubKey[0], Type);
			}
		}
		return true;
}

⌨️ 快捷键说明

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