zoukankan      html  css  js  c++  java
  • c++ DES加密代码

    转载自:http://blog.csdn.net/beyondlpf/article/details/7161964

    #ifndef __DES_H
    #define __DES_H
    class DES{
    public:
        // Encrypt/decrypt the data in "data", according to the "key".
        // Caller is responsible for confirming the buffer size of "data"
        // points to is 8*"blocks" bytes.
        // The data encrypted/decrypted is stored in data.
        // The return code is 1:success, other:failed.

        int encrypt ( unsigned char key[8], unsigned char* data, int blocks = 1 );
        int decrypt ( unsigned char key[8], unsigned char* data, int blocks = 1 );

        // Encrypt/decrypt any size data,according to a special method.
        // Before calling yencrypt, copy data to a new buffer with size
        // calculated by extend.

        int yencrypt ( unsigned char key[8], unsigned char* data, int size );
        int ydecrypt ( unsigned char key[8], unsigned char* in, int blocks, int* size = 0 );
        int extend ( int size ) { return (size/8+1)*8; };

    private:
        void des(unsigned char* in, unsigned char* out, int blocks);
        void des_block(unsigned char* in, unsigned char* out);

    private:
        unsigned long KnL[32];
        enum Mode { ENCRYPT, DECRYPT };
        void deskey(unsigned char key[8], Mode md);
        void usekey(unsigned long *);
        void cookey(unsigned long *);

    private:
        void scrunch(unsigned char *, unsigned long *);
        void unscrun(unsigned long *, unsigned char *);
        void desfunc(unsigned long *, unsigned long *);

    private:
        static unsigned char Df_Key[24];
        static unsigned short bytebit[8];
        static unsigned long bigbyte[24];
        static unsigned char pc1[56];
        static unsigned char totrot[16];
        static unsigned char pc2[48];
        static unsigned long SP1[64];
        static unsigned long SP2[64];
        static unsigned long SP3[64];
        static unsigned long SP4[64];
        static unsigned long SP5[64];
        static unsigned long SP6[64];
        static unsigned long SP7[64];
        static unsigned long SP8[64];
    };
    #endif

    而后,具体实现DES类:

    //des.cpp

    #include <string.h>
    #include "Sinodes.h"

    int DES::encrypt ( unsigned char key[8], unsigned char* data, int blocks )
    {
      if ((!data)||(blocks<1))
          return 0;
      deskey ( key, ENCRYPT );
      des ( data, data, blocks);
      return 1;
    };

    int DES::decrypt ( unsigned char key[8], unsigned char* data, int blocks )
    {
      if ((!data)||(blocks<1))
          return 0;
      deskey ( key, DECRYPT );
      des ( data, data, blocks);
      return 1;
    };

    int DES::yencrypt ( unsigned char key[8], unsigned char* data, int size )
    {
      if ((!data)||(size<1))
        return 0;

      // The last char of data is bitwise complemented and filled the rest
      // buffer.If size is 16, it will extend to 24,and 17 still 24.
      char lastChar = *(data+size-1);
      int blocks = size/8+1;
      memset(data+size, ~lastChar, blocks*8-size);
      deskey( key, ENCRYPT );
      return encrypt ( data, data, blocks);
    };

    int DES::ydecrypt ( unsigned char key[8], unsigned char* data, int blocks, int* size )
    {
      if ( (!data) || (blocks<1) )
        return 0;

      deskey ( key, DECRYPT );
      if ( !decrypt ( data, data, blocks) )
        return 0;
      if ( size != 0 )
      {
        int pos = blocks*8-1;
        char endChar = data[pos];
        while ((pos>0)&&(data[pos]==endChar))
            pos--;
        if ( data[pos] != ~endChar )
          return 0;
        *size = pos+1;
      }
      return 1;
    };

    // -----------------------------------------------------------------------
    // des
    //     Encrpts/Decrypts(according to the key currently loaded int the
    //     internal key reGISter) SOME blocks of eight bytes at address 'in'
    //     into the block at address 'out'. They can be the same.
    //
    //     "in"
    //     "out"
    //     "block" Number of blocks.
    // -----------------------------------------------------------------------
    void DES::des ( unsigned char* in, unsigned char* out, int blocks )
    {
    for (int i = 0; i < blocks; i++,in+=8,out+=8)
        des_block(in,out);
    };

    // -----------------------------------------------------------------------
    // des_block
    //     Encrpts/Decrypts(according to the key currently loaded int the
    //     internal key register) one block of eight bytes at address 'in'
    //     into the block at address 'out'. They can be the same.
    //
    //     "in"
    //     "out"
    // -----------------------------------------------------------------------
    void DES::des_block(unsigned char *in, unsigned char *out)
    {
    unsigned long work[2];

    scrunch(in, work);
    desfunc(work, KnL);
    unscrun(work, out);
    };

    // ----------------------------------------------------------------------
    // deskey
    //     Sets the internal key register (KnR) according to the hexadecimal
    //     key contained in the 8 bytes of hexkey, according to the DES,
    //     for encryption or decrytion according to MODE
    //
    //     "key" is the 64 bits key.
    //     "md" means encryption or decryption.
    // ----------------------------------------------------------------------
    void DES::deskey(unsigned char key[8], Mode md)
    {
    register int ii, j, l, m, n;
    unsigned char pc1m[56], pcr[56];
    unsigned long kn[32];

    for (j = 0; j < 56; j++) {
      l = pc1[j];
      m = l & 07;
      pc1m[j] = (key[l >> 3] & bytebit[m]) ? 1:0;
    }
    for (ii = 0; ii < 16; ii++) {
      if (md == DECRYP) m = (15 - ii) << 1;
        else m = ii << 1;
        n = m + 1;
        kn[m] = kn[n] = 0L;
        for (j = 0; j < 28; j++) {
        l = j + totrot[ii];
        if (l < 28) pcr[j] = pc1m[l];
          else pcr[j] = pc1m[l - 28];
        }
        for (j = 28; j < 56; j++) {
        l = j + totrot[ii];
        if (l < 56) pcr[j] = pc1m[l];
          else pcr[j] = pc1m[l - 28];
        }
        for (j = 0; j < 24; j++) {
        if (pcr[ pc2[j] ]) kn[m] |= bigbyte[j];
        if (pcr[ pc2[j+24] ]) kn[n] |= bigbyte[j];
        }
    }
    cookey(kn);
    return;
    };

    // ----------------------------------------------------------------------
    // cookey
    //     Only called by deskey.
    // -----------------------------------------------------------------------
    void DES::cookey(register unsigned long *raw1)
    {
    register unsigned long *cook, *raw0;
    unsigned long dough[32];
    register int i;

    cook = dough;
    for (i = 0; i < 16; i++, raw1++) {
      raw0 = raw1++;
      *cook = (*raw0 & 0x00fc0000L) << 6;
      *cook |= (*raw0 & 0x00000fc0L) << 10;
      *cook |= (*raw1 & 0x00fc0000L) >> 10;
      *cook++ |= (*raw1 & 0x00000fc0L) >> 6;
      *cook = (*raw0 & 0x0003f000L) << 12;
      *cook |= (*raw0 & 0x0000003fL) << 16;
      *cook |= (*raw1 & 0x0003f000L) >> 4;
      *cook++ |= (*raw1 & 0x0000003fL);
    }
    usekey(dough);
    return;
    };

    // ----------------------------------------------------------------------
    // usekey
    //     Only called by cookey.
    //     Loads the interal key register with the data in cookedkey.
    // -----------------------------------------------------------------------
    void DES::usekey(register unsigned long *from)
    {
    register unsigned long *to, *endp;

    to = KnL, endp = &KnL[32];
    while (to < endp) *to++ = *from++;
    return;
    };

    void DES::scrunch(register unsigned char *outof, register unsigned long *into )
    {
    *into = (*outof++ & 0xffL) << 24;
    *into |= (*outof++ & 0xffL) << 16;
    *into |= (*outof++ & 0xffL) << 8;
    *into++ |= (*outof++ & 0xffL);
    *into = (*outof++ & 0xffL) << 24;
    *into |= (*outof++ & 0xffL) << 16;
    *into |= (*outof++ & 0xffL) << 8;
    *into |= (*outof & 0xffL);
    return;
    };

    void DES::unscrun(register unsigned long *outof, register unsigned char *into)
    {
    *into++ = (*outof >> 24) & 0xffL;
    *into++ = (*outof >> 16) & 0xffL;
    *into++ = (*outof >> 8) & 0xffL;
    *into++ = *outof++ & 0xffL;
    *into++ = (*outof >> 24) & 0xffL;
    *into++ = (*outof >> 16) & 0xffL;
    *into++ = (*outof >> 8) & 0xffL;
    *into = *outof & 0xffL;
    return;
    };

    void DES::desfunc(register unsigned long *block,register unsigned long *keys)
    {
    register unsigned long fval, work, right, leftt;
    register int round;

    leftt = block[0];
    right = block[1];
    work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL;
    right ^= work;
    leftt ^= (work << 4);
    work = ((leftt >> 16) ^ right) & 0x0000ffffL;
    right ^= work;
    leftt ^= (work << 16);
    work = ((right >> 2) ^ leftt) & 0x33333333L;
    leftt ^= work;
    right ^= (work << 2);
    work = ((right >> 8) ^ leftt) & 0x00ff00ffL;
    leftt ^= work;
    right ^= (work << 8);
    right = ((right << 1) | ((right >> 31) & 1L)) & 0xffffffffL;
    work = (leftt ^ right) & 0xaaaaaaaaL;
    leftt ^= work;
    right ^= work;
    leftt = ((leftt << 1) | ((leftt >> 31) & 1L)) & 0xffffffffL;

    for (round = 0; round < 8; round++) {
        work = (right << 28) | (right >> 4);
        work ^= *keys++;
        fval = SP7[work       & 0x3fL];
        fval |= SP5[(work >> 8) & 0x3fL];
        fval |= SP3[(work >> 16) & 0x3fL];
        fval |= SP1[(work >> 24) & 0x3fL];
        work = right ^ *keys++;
        fval |= SP8[work       & 0x3fL];
        fval |= SP6[(work >> 8) & 0x3fL];
        fval |= SP4[(work >> 16) & 0x3fL];
        fval |= SP2[(work >> 24) & 0x3fL];
        leftt ^= fval;
        work = (leftt << 28) | (leftt >> 4);
        work ^= *keys++;
        fval = SP7[work       & 0x3fL];
        fval |= SP5[(work >> 8) & 0x3fL];
        fval |= SP3[(work >> 16) & 0x3fL];
        fval |= SP1[(work >> 24) & 0x3fL];
        work = leftt ^ *keys++;
        fval |= SP8[work       & 0x3fL];
        fval |= SP6[(work >> 8) & 0x3fL];
        fval |= SP4[(work >> 16) & 0x3fL];
      fval |= SP2[(work >> 24) & 0x3fL];
      right ^= fval;
    }
    right = (right << 31) | (right >> 1);
    work = (leftt ^ right) & 0xaaaaaaaaL;
    leftt ^= work;
    right ^= work;
    leftt = (leftt << 31) | ( leftt >> 1);
    work = ((leftt >> 8) ^ right) & 0x00ff00ffL;
    right ^= work;
    leftt ^= (work << 8);
    work = ((leftt >> 2) ^ right) & 0x33333333L;
    right ^= work;
    leftt ^= (work << 2);
    work = ((right >> 16) ^ leftt) & 0x0000ffffL;
    leftt ^= work;
    right ^= (work << 16);
    work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL;
    leftt ^= work;
    right ^= (work << 4);
    *block++ = right;
    *block = leftt;
    return;
    };
    // -----------------------------------------------------------------------
    // Initial of static data members. These data will be used by all the
    // instances of class,and can not be changed.
    // -----------------------------------------------------------------------
    unsigned char DES::Df_Key[24] = {
        0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
        0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
        0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67 };

    unsigned short DES::bytebit[8] = {
        0200, 0100, 040, 020, 010, 04, 02, 01 };

    unsigned long DES::bigbyte[24] = {
        0x800000L, 0x400000L, 0x200000L, 0x100000L,
        0x80000L, 0x40000L, 0x20000L, 0x10000L,
        0x8000L,   0x4000L,   0x2000L,   0x1000L,
        0x800L,   0x400L,   0x200L,   0x100L,
        0x80L,   0x40L,   0x20L,   0x10L,
        0x8L,     0x4L,     0x2L,     0x1L     };

    unsigned char DES::pc1[56] = {
        56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17,
        9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35,
        62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21,
        13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3   };

    unsigned char DES::totrot[16] = {
        1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28 };

    unsigned char DES::pc2[48] = {
        13, 16, 10, 23, 0, 4,     2, 27, 14, 5, 20, 9,
        22, 18, 11, 3, 25, 7,   15, 6, 26, 19, 12, 1,
        40, 51, 30, 36, 46, 54,   29, 39, 50, 44, 32, 47,
        43, 48, 38, 55, 33, 52,   45, 41, 49, 35, 28, 31   };

  • 相关阅读:
    HTML5中的audio在手机端和 微信端的自动播放
    vue框架
    购物车原理
    angular前端框架
    -webkit-line-clamp超过两行就出现省略号
    jQuery事件委托
    淘宝橱窗
    选字游戏
    大众点评订单分库分表实践
    业界难题-“跨库分页”的四种方案
  • 原文地址:https://www.cnblogs.com/java20130723/p/3212293.html
Copyright © 2011-2022 走看看