DES算法代码

DES算法代码
https://blog.csdn.net/bengold1979/article/details/2208930

这是之前的一篇文章,今天才发现之前没有把内容放进来。真是晕头了。幸好看了看评论,有人指出来了。实在是不好意思。现在把代码补上来;声明,不是我自己完全原创的。也是从网上找到一个别人的东西,然后改造了一下。


#ifndef CDES_H_CAESAR__DEF
#define CDES_H_CAESAR__DEF

/*! /Brief CDES类说明 
 *
 * 该类是DES和3DES算法类 
 */
class CDES  
{
public:
    CDES();
    virtual ~CDES();

    //加密解密
    enum    
    {
        ENCRYPT = 0,    //! 加密
        DECRYPT,            //! 解密
    };

    //DES算法的模式
    enum
    {
        ECB     =   0,  //! ECB模式
        CBC             //! CBC模式
    };

    typedef bool    (*PSubKey)[16][48];

    //Pad填充的模式
    enum
    {
        PAD_ISO_1 = 0,  //! ISO_1填充:数据长度不足8比特的倍数,以0x00补足,如果为8比特的倍数,补8个0x00
        PAD_ISO_2,      //! ISO_2填充:数据长度不足8比特的倍数,以0x80,0x00..补足,如果为8比特的倍数,补0x80,0x00..0x00
        PAD_PKCS_7      //! PKCS7填充:数据长度除8余数为n,以(8-n)补足为8的倍数
    };

/* /Brief 补足8位数据 
 *
 * Description: 根据协议对加密前的数据进行填充
 * @param nType :类型:PAD类型
 * @param In :数据串指针
 * @param Out :填充输出串指针
 * @param datalen :数据的长度
 * @param padlen :(in,out)输出buffer的长度,填充后的长度
 * @return true--成功;false--失败; 
 */
    static bool RunPad(int nType,const unsigned char* In,
        unsigned datalen,unsigned char* Out,unsigned& padlen);

/* /Brief 执行DES算法对文本加解密
 *
 * Description :执行DES算法对文本加解密
 * @param bType : 类型:加密ENCRYPT,解密DECRYPT
 * @param bMode : 模式:ECB,CBC
 * @param In :待加密串指针
 * @param Out :待输出串指针
 * @param datalen :待加密串的长度,同时Out的缓冲区大小应大于或者等于datalen
 * @param Key :密钥(可为8位,16位,24位)支持3密钥
 * @param keylen : 密钥长度,多出24位部分将被自动裁减
 * @return true--成功;false--失败; 
 */
    static bool RunDes(bool bType,bool bMode,const unsigned char* In,
        unsigned char* Out,unsigned datalen,const unsigned char* Key,unsigned keylen);

protected:
    //计算并填充子密钥到SubKey数据中
    static void SetSubKey(PSubKey pSubKey, const unsigned char Key[8]);

    //DES单元运算
    static void DES(unsigned char Out[8], const unsigned char In[8],
         const PSubKey pSubKey, bool Type);
};

#endif//CDES_H_CAESAR__DEF

实现代码如下:


// DES.cpp: implementation of the CDES class.
//
//
#include "DES.h"
#include "memory.h"
#include <iostream>
using namespace std; 


// initial permutation IP
const char IP_Table[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
};
// final permutation IP^-1 
const char IPR_Table[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
};
// expansion operation matrix
const char E_Table[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
};
// 32-bit permutation function P used on the output of the S-boxes 
const char P_Table[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
};
// permuted choice table (key) 
const char PC1_Table[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 (table) 
const char PC2_Table[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 
const char LOOP_Table[16] = {
    1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1
};
// The (in)famous S-boxes 
const char S_Box[8][4][16] = {
    // 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
};


CDES::CDES()
{
}

CDES::~CDES()
{
}

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

  返回值 说明:   void
  作       者:    邹德强
  更 新 日 期:  2003.12.19
/*******************************************************************/
static void ByteToBit(bool *Out, const unsigned 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
/*******************************************************************/
static void BitToByte(unsigned 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
/*******************************************************************/
static void 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);
}

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

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

bool CDES::RunDes(bool bType,bool bMode,const unsigned char* In,
        unsigned char* Out,unsigned datalen,const unsigned char* Key,unsigned keylen)
{
    //判断输入合法性
    if(!(In && Out && Key && datalen && keylen>=8))
        return false;
    unsigned char inbuf[datalen + 8];
    memset(inbuf, 0x00, sizeof(inbuf)); 
    memcpy(inbuf, In, datalen); 
    unsigned char* tempBuf;
    unsigned padlen = datalen; 
    //只处理8的整数倍,不足长度自己填充
    if(datalen & 0x00000007)
    {
        if (!RunPad(PAD_PKCS_7, In, datalen, inbuf, padlen))
            return false;
        tempBuf = inbuf; 
    }
    else
    {
        tempBuf = inbuf;
    }

    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]);
    }

    if(bMode == ECB)    //ECB模式
    {
        if(nKey ==  1)  //单Key
        {
            int j = padlen>>3; 
            for(int i=0,j = padlen>>3;i<j;++i,Out+=8,tempBuf+=8)
            {
                DES(Out,tempBuf,&m_SubKey[0],bType);
            }
        }
        else
        if(nKey == 2)   //3DES 2Key
        {
            for(int i=0,j = padlen>>3;i<j;++i,Out+=8,tempBuf+=8)
            {
                DES(Out,tempBuf,&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=padlen>>3;i<j;++i,Out+=8,tempBuf+=8)
            {
                DES(Out,tempBuf,&m_SubKey[bType? 2 : 0],bType);
                DES(Out,Out,&m_SubKey[1],!bType);
                DES(Out,Out,&m_SubKey[bType? 0 : 2],bType); 
            }
        }
    }   
    else                //CBC模式
    {
        unsigned char   cvec[8] =   ""; //扭转向量
        unsigned char   cvin[8] =   ""; //中间变量

        if(nKey == 1)   //单Key
        {
            for(int i=0,j=padlen>>3;i<j;++i,Out+=8,tempBuf+=8)
            {
                if(bType    ==  CDES::ENCRYPT)
                {
                    for(int j=0;j<8;++j)        //将输入与扭转变量异或
                    {
                        cvin[j] =   tempBuf[j] ^ cvec[j];
                    }
                }
                else
                {
                    memcpy(cvin,tempBuf,8);
                }

                DES(Out,cvin,&m_SubKey[0],bType);

                if(bType    ==  CDES::ENCRYPT)
                {
                    memcpy(cvec,Out,8);         //将输出设定为扭转变量
                }
                else
                {
                    for(int j=0;j<8;++j)        //将输出与扭转变量异或
                    {
                        Out[j]  =   Out[j] ^ cvec[j];
                    }
                    memcpy(cvec,cvin,8);            //将输入设定为扭转变量
                }
            }
        }
        else
        if(nKey == 2)   //3DES CBC 2Key
        {
            for(int i=0,j=padlen>>3;i<j;++i,Out+=8,tempBuf+=8)
            {
                if(bType    ==  CDES::ENCRYPT)
                {
                    for(int j=0;j<8;++j)        //将输入与扭转变量异或
                    {
                        cvin[j] =   tempBuf[j] ^ cvec[j];
                    }
                }
                else
                {
                    memcpy(cvin,tempBuf,8);
                }

                DES(Out,cvin,&m_SubKey[0],bType);
                DES(Out,Out,&m_SubKey[1],!bType);
                DES(Out,Out,&m_SubKey[0],bType);

                if(bType    ==  CDES::ENCRYPT)
                {
                    memcpy(cvec,Out,8);         //将输出设定为扭转变量
                }
                else
                {
                    for(int j=0;j<8;++j)        //将输出与扭转变量异或
                    {
                        Out[j]  =   Out[j] ^ cvec[j];
                    }
                    memcpy(cvec,cvin,8);            //将输入设定为扭转变量
                }
            }
        }
        else            //3DES CBC 3Key
        {
            for(int i=0,j=padlen >>3;i<j;++i,Out+=8,tempBuf+=8)
            {
                if(bType    ==  CDES::ENCRYPT)
                {
                    for(int j=0;j<8;++j)        //将输入与扭转变量异或
                    {
                        cvin[j] =   tempBuf[j] ^ cvec[j];
                    }
                }
                else
                {
                    memcpy(cvin,tempBuf,8);
                }

                DES(Out,cvin,&m_SubKey[bType ? 2 : 0],bType);
                DES(Out,Out,&m_SubKey[1],!bType);
                DES(Out,Out,&m_SubKey[bType ? 0 : 2],bType);

                if(bType    ==  CDES::ENCRYPT)
                {
                    memcpy(cvec,Out,8);         //将输出设定为扭转变量
                }
                else
                {
                    for(int j=0;j<8;++j)        //将输出与扭转变量异或
                    {
                        Out[j]  =   Out[j] ^ cvec[j];
                    }
                    memcpy(cvec,cvin,8);            //将输入设定为扭转变量
                }
            }
        }
    }

    return true;
}




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

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

  更 新 日 期:  2003.12.19
/*******************************************************************/
bool    CDES::RunPad(int nType, const unsigned char* In,
         unsigned datalen, unsigned char* Out, unsigned& padlen)
{
    if (nType < PAD_ISO_1 || nType > PAD_PKCS_7)
        return false;

    if (In == NULL || datalen < 0 || Out == NULL)
        return false;
    int res = (datalen & 0x00000007);

    if (res == 0)
    {
        padlen = datalen;
        memcpy(Out, In, datalen); 
        return true; 
    } 

    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,0x00,8-res);
    }
    else
    {
        return false;
    }

    return true;
}

//计算并填充子密钥到SubKey数据中
void CDES::SetSubKey(PSubKey pSubKey, const unsigned 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 CDES::DES(unsigned char Out[8], const unsigned char In[8], const PSubKey pSubKey, bool Type)
{
    bool M[64], tmp[32], *Li=&M[0], *Ri=&M[32];
    ByteToBit(M, In, 64);
    Transform(M, M, IP_Table, 64);
    if( Type == ENCRYPT )
    {
        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);              //组织成字符
}

感谢,这份代码是对的,找了好几份测试都不对,搞了几天,真痛苦啊。

DES算法的C语言代码及实现 首先新建头文件des_encode.H 内容如下: void EncodeMain(); //EncodeMain function void DecodeMain(); //Sorry ,it has not used void Decode(int *str,int *keychar); //decode :input 8 chars,8 keychars void Encode(int *str,int *keychar); //encode: input 8 chars,8 keychars void keyBuild(int *keychar); //create key array void StrtoBin(int *midkey,int *keychar); //change into binary void keyCreate(int *midkey2,int movebit,int i); //call by keyBuild void EncodeData(int *lData,int *rData,int *srt); //encodedata function void F(int *rData,int *key); //F function void Expand(int *rData,int *rDataP); //Expand function void ExchangeS(int *rDataP,int *rData); //S-diagram change void ExchangeP(int *rData); //P change void FillBin(int *rData,int n,int s); // data to binary;call by S-Diagram change function void DecodeData(int *str,int *lData,int *rData); //DecodeData from binary int IP1[]={58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, //initial change 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 IP2[]={40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31, //opp initial change 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 }; int s[][4][16]={{ //S-diagram array {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} }, { {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} }, { {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} }, { {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} }, { {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} }, { {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} }, { {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} }, { {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} } }; int Ex[48]={ 32,1,2,3,4,5, //Expand array 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 }; int P[32]={16,7,20,21, //P-change 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 PC1[56]={57,49,41,33,25,17,9, //PC-1 in keyBuild 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,33,15, 7,62,54,46,38,30,22, 14,6,61,53,45,37,29, 21,13,5,28,20,12,4 }; int PC2[48]={14,17,11,24,1,5, //PC-2 in keyBuild 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 }; 再创建des.cpp 内容如下: #include<stdio.h> #include<string.h> #include"des_encode.h" int key[16][48]; char str[8]; void main() //main function { EncodeMain(); } void EncodeMain() //EncodeMain function { int i; char keychar[8]; int key2[8]; int strkey[8]; printf("请输入8个要加密的字符:\n"); for(i=0;i<8;i++) scanf("%c",&str[i]); getchar(); for(i=0;i<8;i++) strkey[i]=str[i]; printf("\n输入明文的十六进制为:\n"); for(i=0;i<8;i++) printf("%10x",strkey[i]); printf("\n请输入密钥(8个字符):\n"); for(i=0;i<8;i++) scanf("%c",&keychar[i]); for(i=0;i<8;i++) key2[i]=keychar[i]; getchar(); // printf("%c",keychar[i]); Encode(strkey,key2); printf("\n加密后十六进制密文是:\n"); for(i=0;i<8;i++) printf("%10x",strkey[i]); printf("\n\n清输入解密密码\n"); for(i=0;i<8;i++) scanf("%c",&keychar[i]); for(i=0;i<8;i++) key2[i]=keychar[i]; Decode(strkey,key2); for(i=0;i<8;i++) printf("%10x",strkey[i]); for(i=0;i<8;i++) str[i]=strkey[i]; printf("\n明文为:\t"); for(i=0;i<8;i++) printf("%c",str[i]); printf("\n\n"); } void keyBuild(int *keychar){ //create key array int i,j; int movebit[]={1,1,2,2,2,2,2,2, 1,2,2,2,2,2,2,1}; int midkey2[56]; int midkey[64]; StrtoBin(midkey,keychar); for(i=0;i<56;i++) midkey2[i]=midkey[PC1[i]-1]; for(i=0;i<16;i++) keyCreate(midkey2,movebit[i],i); } void StrtoBin(int *midkey,int *keychar){ //change into binary int trans[8],i,j,k,n; n=0; for(i=0;i<8;i++){ j=0; while(keychar[i]!=0){ trans[j]=keychar[i]%2; keychar[i]=keychar[i]/2; j++; } for(k=j;k<8;k++)trans[k]=0; for(k=0;k<8;k++) midkey[n++]=trans[7-k]; } } void keyCreate(int *midkey2,int movebit,int n){ int i,temp[4]; temp[0]=midkey2[0]; temp[1]=midkey2[1]; temp[2]=midkey2[28]; temp[3]=midkey2[29]; if(movebit==2){ for(i=0;i<26;i++){ midkey2[i]=midkey2[i+2]; midkey2[i+28]=midkey2[i+30]; } midkey2[26]=temp[0];midkey2[27]=temp[1]; midkey2[54]=temp[2];midkey2[55]=temp[3]; } else { for(i=0;i<27;i++){ midkey2[i]=midkey2[i+1]; midkey2[i+28]=midkey2[i+29]; } midkey2[27]=temp[0];midkey2[55]=temp[2]; } for(i=0;i<48;i++) key[n][i]=midkey2[PC2[i]-1]; } void EncodeData(int *lData,int *rData,int *str){ //encodedata function int i,j,temp[8],lint,rint;//int h; int data[64]; lint=0,rint=0; for(i=0;i<4;i++){ j=0; while(str[i]!=0){ temp[j]=str[i]%2; str[i]=str[i]/2; j++; } while(j<8)temp[j++]=0; for(j=0;j<8;j++) lData[lint++]=temp[7-j]; j=0; while(str[i+4]!=0){ temp[j]=str[i+4]%2; str[i+4]=str[i+4]/2; j++; } while(j<8)temp[j++]=0; for(j=0;j<8;j++)rData[rint++]=temp[7-j]; } for(i=0;i<32;i++){ data[i]=lData[i]; data[i+32]=rData[i]; } for(i=0;i<32;i++){ lData[i]=data[IP1[i]-1];//printf("P1:%5d:%5d,%5d\n",IP1[i],lData[i],data[IP1[i]-1]); rData[i]=data[IP1[i+32]-1]; } } void F(int *rData,int *key){ //F function int i,rDataP[48]; Expand(rData,rDataP); for(i=0;i<48;i++){ rDataP[i]=rDataP[i]^key[i];// printf("%10d",rDataP[i]);if((i+1)%6==0)printf("\n"); } ExchangeS(rDataP,rData); ExchangeP(rData); } void Expand(int *rData,int *rDataP){ //Expand function int i; for(i=0;i<48;i++) rDataP[i]=rData[Ex[i]-1]; } void ExchangeS(int *rDataP,int *rData){ //S-diagram change int i,n,linex,liney; linex=liney=0; for(i=0;i<48;i+=6){ n=i/6; //printf("%10d\n",(rDataP[i]<<1)); linex=(rDataP[i]<<1)+rDataP[i+5]; liney=(rDataP[i+1]<<3)+(rDataP[i+2]<<2)+(rDataP[i+3]<<1)+rDataP[i+4]; FillBin(rData,n,s[n][linex][liney]); } } void ExchangeP(int *rData){ //P change int i,temp[32]; for(i=0;i<32;i++) temp[i]=rData[i]; for(i=0;i<32;i++) rData[i]=temp[P[i]-1]; } void FillBin(int *rData,int n,int s){ // data to binary;call by S-Diagram change function int temp[4],i; for(i=0;i<4;i++){ temp[i]=s%2; s=s/2; } for(i=0;i<4;i++) rData[n*4+i]=temp[3-i]; } void DecodeData(int *str,int *lData,int *rData){ //DecodeData from binary int i;int a,b;int data[64]; a=0,b=0; for(i=0;i<32;i++){ data[i]=lData[i]; data[i+32]=rData[i]; } for(i=0;i<32;i++){ lData[i]=data[IP2[i]-1]; rData[i]=data[IP2[i+32]-1]; } for(i=0;i<32;i++){ a=(lData[i]&0x1)+(a<<1); b=(rData[i]&0x1)+(b<<1); if((i+1)%8==0){ str[i/8]=a;a=0;//printf("%d",i/8); str[i/8+4]=b;b=0;//printf("%d",i/8+4); } } } void Encode(int *str,int *keychar){ //encode: input 8 chars,8 keychars int lData[32],rData[32],temp[32],rDataP[48]; int i,j; keyBuild(keychar); EncodeData(lData,rData,str); for(i=0;i<16;i++){ for(j=0;j<32;j++) temp[j]=rData[j]; F(rData,key[i]); for(j=0;j<32;j++){ rData[j]=rData[j]^lData[j]; } for(j=0;j<32;j++) lData[j]=temp[j]; } DecodeData(str,rData,lData); } void Decode(int *str,int *keychar){ //decode :input 8 chars,8 keychars int lData[32],rData[32],temp[32],rDataP[48]; int i,j; keyBuild(keychar); EncodeData(lData,rData,str); //这个位置 for(i=0;i<16;i++){ for(j=0;j<32;j++) temp[j]=rData[j]; F(rData,key[15-i]); for(j=0;j<32;j++){ rData[j]=rData[j]^lData[j]; } for(j=0;j<32;j++){ lData[j]=temp[j]; } } DecodeData(str,rData,lData); }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值