转载并学习实现三重DES加密解密代码(一)

作者:finallyliuyu 出处:博客园

声明:此篇博文代码来自于邹德强先生。由于目前找到的版本是残缺版,所以我又进行了补全。读一份好代码,可以领略到作者的编程风格和语言驾驭能力,同时又能从其中汲取养分。现将我所修改后的DES加密解密代码全部张贴出来,有需要的也可以在上面继续改动

comon.h

#ifndef _COMMON_H
#define _COMMON_H
typedef 
bool (* PSubKey)[16][48];
#endif
myDES.h
#ifndef _myDES_H
#define _myDES_H
#include 
"common.h"
#include
<stdio.h>
class myDES
{
public:
    myDES();
    
~myDES();
     
void ByteToBit(bool *Out, const char *In, int bits);
     
void BitToByte(char *Out, const bool *In, int bits);
     
void RotateL(bool *In, int len, int loop);
     
void RotateR(bool *In,int len,int loop);
     
void Xor(bool *InA, const bool *InB, int len);
     
void Transform(bool *Out, bool *In, const char *Table, int len);
     
void S_func(bool Out[32], const bool In[48]);
     
void F_func(bool In[32], const bool Ki[48]);
     
bool RunDes(bool bType,char* In,char* Out,unsigned datalen,const char* Key,const unsigned char keylen);
     
bool RunPad(int nType,const char* In,unsigned datalen,char* Out,unsigned& padlen);
     
void SetSubKey(PSubKey pSubKey, const char Key[8]);
     
void DES(char Out[8], char In[8], const PSubKey pSubKey,bool nType);
     
bool myRunDES(bool bType,char* In,char* Out,unsigned datalen,const char* Key,const unsigned char keylen);







    
};
#endif
myDES.cpp
// DES.cpp: implementation of the myDES class.
//
//////////////////////////////////////////////////////////////////////
#include "myDES.h"
#include 
"memory.h"


////////////////////////////////////////////////////////////////////////
// initial permutation IP
const char IP_Table[64= {
    
585042342618102605244362820124,
        
625446383022146645648403224168,
        
574941332517,  91595143352719113,
        
615345372921135635547393123157
};
// final permutation IP^-1 
const char IPR_Table[64= {
    
408481656246432397471555236331,
        
386461454226230375451353216129,
        
364441252206028353431151195927,
        
34242105018582633141,  949175725
};
// expansion operation matrix
const char E_Table[48= {
    
32,  1,  2,  3,  4,  5,  4,  5,  6,  7,  8,  9,
        
8,  910111213121314151617,
        
161718192021202122232425,
        
2425262728292829303132,  1
};
// 32-bit permutation function P used on the output of the S-boxes 
const char P_Table[32= {
    
1672021291228171,  1523265,  183110,
        
2,  8241432273,  9,  1913306,  22114,  25
};
// permuted choice table (key) 
const char PC1_Table[56= {
    
574941332517,  9,  1585042342618,
        
10,  259514335271911,  360524436,
        
63554739312315,  7625446383022,
        
14,  661534537292113,  5282012,  4
};
// permuted choice key (table) 
const char PC2_Table[48= {
    
14171124,  1,  5,  32815,  62110,
        
231912,  426,  816,  7272013,  2,
        
415231374755304051453348,
        
444939563453464250362932
};
// number left rotations of pc1 
const char LOOP_Table[16= {
    
1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1
};
const char LOOPR_Table[16]={1,2,2,2,2,2,2,1,2,2,2,2,2,2,1,0};
// The (in)famous S-boxes 
const char S_Box[8][4][16= {
    
// S1 
    14,     4,    13,     1,  21511,  8,  310,  612,  5,  9,  0,  7,
        
015,  7,  414,  213,  110,  61211,  9,  5,  3,  8,
        
4,  114,  813,  6,  2111512,  9,  7,  310,  5,  0,
        
1512,  8,  2,  4,  9,  1,  7,  511,  31410,  0,  613,
        
// S2 
        15,  1,  814,  611,  3,  4,  9,  7,  21312,  0,  510,
        
313,  4,  715,  2,  81412,  0,  110,  6,  911,  5,
        
014,  71110,  413,  1,  5,  812,  6,  9,  3,  215,
        
13,  810,  1,  315,  4,  211,  6,  712,  0,  514,  9,
        
// S3 
        10,  0,  914,  6,  315,  5,  11312,  711,  4,  2,  8,
        
13,  7,  0,  9,  3,  4,  610,  2,  8,  514121115,  1,
        
13,  6,  4,  9,  815,  3,  011,  1,  212,  51014,  7,
        
11013,  0,  6,  9,  8,  7,  41514,  311,  5,  212,
        
// S4 
        71314,  3,  0,  6,  910,  1,  2,  8,  51112,  415,
        
13,  811,  5,  615,  0,  3,  4,  7,  212,  11014,  9,
        
10,  6,  9,  01211,  71315,  1,  314,  5,  2,  8,  4,
        
315,  0,  610,  113,  8,  9,  4,  51112,  7,  214,
        
// S5 
        212,  4,  1,  71011,  6,  8,  5,  31513,  014,  9,
        
1411,  212,  4,  713,  1,  5,  01510,  3,  9,  8,  6,
        
4,  2,  1111013,  7,  815,  912,  5,  6,  3,  014,
        
11,  812,  7,  114,  213,  615,  0,  910,  4,  5,  3,
        
// S6 
        12,  11015,  9,  2,  6,  8,  013,  3,  414,  7,  511,
        
1015,  4,  2,  712,  9,  5,  6,  11314,  011,  3,  8,
        
91415,  5,  2,  812,  3,  7,  0,  410,  11311,  6,
        
4,  3,  212,  9,  515101114,  1,  7,  6,  0,  813,
        
// S7 
        411,  21415,  0,  813,  312,  9,  7,  510,  6,  1,
        
13,  011,  7,  4,  9,  11014,  3,  512,  215,  8,  6,
        
1,  4111312,  3,  7141015,  6,  8,  0,  5,  9,  2,
        
61113,  8,  1,  410,  7,  9,  5,  01514,  2,  312,
        
// S8 
        13,  2,  8,  4,  61511,  110,  9,  314,  5,  012,  7,
        
11513,  810,  3,  7,  412,  5,  611,  014,  9,  2,
        
711,  4,  1,  91214,  2,  0,  6101315,  3,  5,  8,
        
2,  114,  7,  410,  8131512,  9,  0,  3,  5,  611
};


myDES::myDES()
{
    
}

myDES::
~myDES()
{
}

/*******************************************************************/
/*
  函 数 名 称:    ByteToBit
  功 能 描 述:    把BYTE转化为Bit流
  参 数 说 明:    Out:    输出的Bit流[in][out]
                In:        输入的BYTE流[in]
                bits:    Bit流的长度[in]

  返回值 说明:    void
  作       者:    邹德强
  更 新 日 期:    2003.12.19
/******************************************************************
*/
void myDES::ByteToBit(bool *Out, const char *In, int bits)
{
    
for(int i=0; i<bits; ++i)
        Out[i] 
= (In[i>>3]>>(7 - i&7)) & 1;
}

/*******************************************************************/
/*
  函 数 名 称:    BitToByte
  功 能 描 述:    把Bit转化为Byte流
  参 数 说 明:    Out:    输出的BYTE流[in][out]
                In:        输入的Bit流[in]
                bits:    Bit流的长度[in]

  返回值 说明:    void
  作       者:    邹德强
  更 新 日 期:    2003.12.19
/******************************************************************
*/
 
void myDES:: 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]<<(7 - i&7);
}



/*******************************************************************/
/*
  函 数 名 称:    RotateL
  功 能 描 述:    把BIT流按位向左迭代
  参 数 说 明:    In:        输入的Bit流[in]
                len:    Bit流的长度[in]
                loop:    向左迭代的长度

  返回值 说明:    void
  作       者:    邹德强
  更 新 日 期:    2003.12.19
/******************************************************************
*/
 
void myDES::RotateL(bool *In, int len, int loop)
{
    
bool Tmp[256];

    memcpy(Tmp, In, loop);
    memcpy(In, In
+loop, len-loop);
    memcpy(In
+len-loop, Tmp, loop);
}
 
 
void myDES::RotateR(bool *In,int len,int loop)
 {
     
bool Tmp[256];
     memcpy(Tmp,In,len
-loop);
     memcpy(In,In
+len-loop,loop);
     memcpy(In
+len-loop,Tmp,len-loop);

 }



/*******************************************************************/
/*
  函 数 名 称:    Xor
  功 能 描 述:    把两个Bit流进行异或
  参 数 说 明:    InA:    输入的Bit流[in][out]
                InB:    输入的Bit流[in]
                loop:    Bit流的长度

  返回值 说明:    void
  作       者:    邹德强
  更 新 日 期:    2003.12.19
/******************************************************************
*/
 
void myDES::Xor(bool *InA, const bool *InB, int len)
{
    
for(int i=0; i<len; ++i)
        InA[i] 
^= InB[i];
}


/*******************************************************************/
/*
  函 数 名 称:    Transform
  功 能 描 述:    把两个Bit流按表进行位转化
  参 数 说 明:    Out:    输出的Bit流[out]
                In:        输入的Bit流[in]
                Table:    转化需要的表指针
                len:    转化表的长度

  返回值 说明:    void
  作       者:    邹德强
  更 新 日 期:    2003.12.19
/******************************************************************
*/
 
void myDES::Transform(bool *Out, bool *In, const char *Table, int len)
{
    
bool Tmp[256];

    
for(int i=0; i<len; ++i)
        Tmp[i] 
= In[ Table[i]-1 ];
    memcpy(Out, Tmp, len);
}



/*******************************************************************/
/*
  函 数 名 称:    S_func
  功 能 描 述:    实现数据加密S BOX模块
  参 数 说 明:    Out:    输出的32Bit[out]
                In:        输入的48Bit[in]

  返回值 说明:    void
  作       者:    邹德强
  更 新 日 期:    2003.12.19
/******************************************************************
*/
 
void myDES::S_func(bool Out[32], const bool In[48])
{
    
for(char i=0,j,k; i<8++i,In+=6,Out+=4
    {
        j 
= (In[0]<<1+ In[5];
        k 
= (In[1]<<3+ (In[2]<<2+ (In[3]<<1+ In[4];    //组织SID下标
        
        
for(int l=0; l<4++l)                                //把相应4bit赋值
            Out[l] = (S_Box[i][j][k]>>(3 - l)) & 1;
    }
}


/*******************************************************************/
/*
  函 数 名 称:    F_func
  功 能 描 述:    实现数据加密到输出P
  参 数 说 明:    Out:    输出的32Bit[out]
                In:        输入的48Bit[in]

  返回值 说明:    void
  作       者:    邹德强
  更 新 日 期:    2003.12.19
/******************************************************************
*/
 
void myDES::F_func(bool In[32], const bool Ki[48])
{
    
bool MR[48];
    Transform(MR, In, E_Table, 
48);
    Xor(MR, Ki, 
48);
    S_func(In, MR);
    Transform(In, In, P_Table, 
32);
}


/*******************************************************************/
/*
  函 数 名 称:    RunDes
  功 能 描 述:    执行DES算法对文本加解密
  参 数 说 明:    bType    :类型:加密ENCRYPT,解密DECRYPT
                bMode    :模式:ECB,CBC
                In        :待加密串指针
                Out        :待输出串指针
                datalen    :待加密串的长度,同时Out的缓冲区大小应大于或者等于datalen
                Key        :密钥(可为8位,16位,24位)支持3密钥
                keylen    :密钥长度,多出24位部分将被自动裁减

  返回值 说明:    bool    :是否加密成功
  作       者:    邹德强
  更 新 日 期:    2003.12.19
/******************************************************************
*/
bool myDES::RunDes(bool bType,char* In,char* Out,unsigned datalen,const char* Key,const unsigned char keylen)
{
    
//判断输入合法性
    if(!(In && Out && Key && datalen && keylen>=8))
        
return false;
    
//只处理8的整数倍,不足长度自己填充
    if(datalen & 0x00000007)
        
return false;
    
    
bool                m_SubKey[3][16][48];        //秘钥
    
//构造并生成SubKeys
    unsigned char nKey    =    (keylen>>3)>3 ? 3: (keylen>>3);
    
for(int i=0;i<nKey;i++)
    {
        SetSubKey(
&m_SubKey[i],&Key[i<<3]);
    }

        
//ECB模式
    
        
if(nKey    ==    1)    //单Key
        {
            
for(int i=0,j=datalen>>3;i<j;++i,Out+=8,In+=8)
            {
                DES(Out,In,
&m_SubKey[0],bType);
            }
        }
        
else
        
if(nKey == 2)    //3DES 2Key
        {
            
for(int i=0,j=datalen>>3;i<j;++i,Out+=8,In+=8)
            {
                DES(Out,In,
&m_SubKey[0],bType);
                DES(Out,Out,
&m_SubKey[1],!bType);
                DES(Out,Out,
&m_SubKey[0],bType);
            }
        }
        
else            //3DES 3Key
        {
            
for(int i=0,j=datalen>>3;i<j;++i,Out+=8,In+=8)
            {
                DES(Out,In,
&m_SubKey[bType? 2 : 0],bType);
                DES(Out,Out,
&m_SubKey[1],!bType);
                DES(Out,Out,
&m_SubKey[bType? 0 : 2],bType);    
            }
        }
        
    
    
    
return true;
}




/*******************************************************************/
/*
  函 数 名 称:    RunPad
  功 能 描 述:    根据协议对加密前的数据进行填充
  参 数 说 明:    bType    :类型:PAD类型
                In        :数据串指针
                Out        :填充输出串指针
                datalen    :数据的长度
                padlen    :(in,out)输出buffer的长度,填充后的长度

  返回值 说明:    bool    :是否填充成功
  作       者:    邹德强
  修 改 历 史:    

  更 新 日 期:    2003.12.19
/******************************************************************
*/
/*bool    myDES::RunPad(int nType,const char* In,unsigned datalen,char* Out,unsigned& padlen)
{
    int res = (datalen & 0x00000007);
    
    
    if(padlen< (datalen+8-res))
    {
        return false;
    }
    else
    {
        padlen    =    (datalen+8-res);
        memcpy(Out,In,datalen);
        if(nType==PAD_ISO_1)
        {
            memset(Out+datalen,0x00,8-res);
        }

        else if(nType==PAD_ISO_2)
        {
            memset(Out+datalen,0x80,1);
            memset(Out+datalen,0x00,7-res);
        }
        else if(nType==PAD_PKCS_7)
        {
            memset(Out+datalen,8-res,8-res);
        }
        else
        {
            return false;
        }

        return true;
    }
    
    
    
}
*/
bool    myDES::RunPad(int nType,const char* In,unsigned datalen,char* Out,unsigned& padlen)
{
    
int res = (datalen & 0x00000007);
    memcpy(Out,In,datalen);
    
if (res)
    {
        memset(Out
+datalen,0x00,8-res);
        
return true;

    }
    
else
    {
        
return false;
    }


    

            
}






//计算并填充子密钥到SubKey数据中
void myDES::SetSubKey(PSubKey pSubKey, const char Key[8])
{
    
bool K[64], *KL=&K[0], *KR=&K[28];
    ByteToBit(K, Key, 
64);
    Transform(K, K, PC1_Table, 
56);
    
for(int i=0; i<16++i) 
    {
        
        
            RotateL(KL, 
28, LOOP_Table[i]);
            RotateL(KR, 
28, LOOP_Table[i]);    
           Transform((
*pSubKey)[i], K, PC2_Table, 48);
    }
}



//DES单元运算
void myDES::DES(char Out[8], char In[8], const PSubKey pSubKey,bool nType)
{
    
bool M[64], tmp[32], *Li=&M[0], *Ri=&M[32];
    ByteToBit(M, In, 
64);
    Transform(M, M, IP_Table, 
64);
    
if( nType )
    {
        
for(int i=0; i<16++i)
        {
            memcpy(tmp, Ri, 
32);        //Ri[i-1] 保存
            F_func(Ri, (*pSubKey)[i]);    //Ri[i-1]经过转化和SBox输出为P
            Xor(Ri, Li, 32);            //Ri[i] = P XOR Li[i-1]
            memcpy(Li, tmp, 32);        //Li[i] = Ri[i-1]
        }
    }
    
else
    {
        
for(int i=15; i>=0--i) 
        {
            memcpy(tmp, Ri, 
32);        //Ri[i-1] 保存
            F_func(Ri, (*pSubKey)[i]);    //Ri[i-1]经过转化和SBox输出为P
            Xor(Ri, Li, 32);            //Ri[i] = P XOR Li[i-1]
            memcpy(Li, tmp, 32);        //Li[i] = Ri[i-1]
        }
    }
    RotateL(M,
64,32);                    //Ri与Li换位重组M
    Transform(M, M, IPR_Table, 64);        //最后结果进行转化
    BitToByte(Out, M, 64);                //组织成字符
}
bool myDES::myRunDES(bool bType,char* In,char* Out,unsigned datalen,const char* Key,const unsigned char keylen)
{


    
return true;
    
}
原文地址:https://www.cnblogs.com/finallyliuyu/p/1917600.html