加密算法C++实现类源码

#ifndef CIPHER_H
#define CIPHER_H

#define SAFE_DELARRAY(p) {if(p)delete [] p; p = NULL;}
#define SAFE_DELETE(p) {if(p)delete p; p = NULL;}

class CCaeser //
{
public:
 CCaeser();
 ~CCaeser();
 void SetKey(int k);
 char *Encipher(const char* plain);
 char *Decipher(const char* cipher);
private:
 int m_nKey;
 char *m_pOut;
};

class CDes
{
public:
 CDes();
 virtual ~CDes();
 void SetKey(const char* );
 char * Encipher(const char *plain);
 char * Decipher(const char *cipher);
private:
 void ls1();
 void rs1();
 void lst(int time);
 void rst(int time);
 void IP1();
 void IP2();
 char *m_strkey;
 char *m_pOut;
private:
 unsigned char left[32];
 unsigned char right[32];
 unsigned char brige[32];  //中介作用
 unsigned char zhong[32];
 unsigned char large[48];  //由右部拓展得到48位
 unsigned char bitci[64];
 unsigned char bitpl[64];
 unsigned char bitip[64];
 unsigned char e1key[64];
 unsigned char e2key[56];
 unsigned char fkey[48];
};

class CIdea 
{
 #ifndef BLOCKSIZE
 #define BLOCKSIZE 4
 #endif
 #ifndef ROUND
 #define ROUND 8
 #endif
 #ifndef KEYSIZE
 #define KEYSIZE 6
 #endif
 #ifndef CARDINALITY
 #define CARDINALITY 65536
 #endif
 #ifndef SHIFTLEFT
 #define SHIFTLEFT 25
 #endif
private:
 WORD wKeySeed[ ROUND ];          // 密钥种子
 WORD pwEncryptKey [ KEYSIZE * ROUND + BLOCKSIZE ];  // 加密密钥
 WORD pwDecryptKey [ KEYSIZE * ROUND + BLOCKSIZE ];  // 解密密钥

 WORD Addition ( WORD x , WORD y );
 void GenDecryptKey();
 
 //   生成加密密钥
 void GenEncryptKey ( );
 
 //   对密钥种子循环左移25位,生成一组密钥子块
 void GenSubKey ( );
 
 //   求一整数在模65537下的逆
 WORD Inverse ( WORD x );
 
 /* 
 加密或解密过程中的单轮迭代
 sTurn  指出迭代的轮数
 bCrypt 指出是加密还是解密。若为true,则是加密;若为false,则是解密 
 */
 void Iteration ( short sTurn , bool bCrypt);
 
 //   求两数模65537之积
 WORD Multi ( WORD x , WORD y );
public:
 CIdea();
 virtual ~CIdea();
 WORD wCipher [ BLOCKSIZE ] ;   // 密文块
 WORD wPlain [ BLOCKSIZE ] ;    // 明文块
 void Encipher ( ); //加密函数
 void Decipher ();  //解密函数
 
 //   设置新的密钥种子,并产生新的加密和解密密钥
 void SetNewKey( unsigned short int * KeySeed);
};

#endif

 

/

#include "stdafx.h"
#include "Cipher.h"

CCaeser//
CCaeser::CCaeser()
{
 m_nKey = 0;
 m_pOut = NULL;
}

CCaeser::~CCaeser()
{
 SAFE_DELARRAY(m_pOut);
}

void CCaeser::SetKey(int k)
{
 if(k < 0 || k > 25)
  m_nKey = 0;
 else
  m_nKey = k;
}
 
char* CCaeser::Encipher(const char* plain)
{
 int n,i;
 n=strlen(plain);
 SAFE_DELARRAY(m_pOut);
 m_pOut = new char [n+1];
 for(i=0;i<=n-1;i++)
 {
  if(plain[i] >= 'a' && plain[i] <= 'z')
   m_pOut[i] = 'a' + (plain[i] - 'a' + m_nKey)%26;
  else if(plain[i] >= 'A' && plain[i] <= 'Z')
   m_pOut[i] = 'A' + (plain[i] - 'A' + m_nKey)%26;
  else
   m_pOut[i] = plain[i];
 }
 m_pOut[n]='\0';
 return m_pOut;
}

char* CCaeser::Decipher(const char* cipher)
{
 int n,i;
 n = strlen(cipher);
 SAFE_DELARRAY(m_pOut);
 m_pOut = new char [n+1];
 for( i = 0; i <= n-1; i++ )
 {
  if(cipher[i] >= 'a'&& cipher[i] <= 'z')
   m_pOut[i]='a'+(cipher[i] - 'a' - m_nKey + 26)%26;
  else if(cipher[i] >= 'A' && cipher[i] <= 'Z')
   m_pOut[i]='A'+(cipher[i] - 'A'- m_nKey + 26)%26;
  else
   m_pOut[i] = cipher[i];
 }
 m_pOut[n]='\0';
 return m_pOut;
}

CDes//

CDes::CDes()
{
 m_strkey = new char[10];
 m_pOut = NULL;
}

CDes::~CDes()
{
 SAFE_DELARRAY(m_strkey)
 SAFE_DELARRAY(m_pOut);
}


int ip1[64]={
 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,
    56, 48, 40, 32, 24, 16,  8, 0,
 58, 50, 42, 34, 26, 18, 10, 2,
 60, 52, 44, 36, 28, 20, 12, 4,
 62, 54, 46, 38, 30, 22, 14, 6};

int ip2[64]={
 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,
 32, 0, 40,  8, 48, 16, 56, 24};

int lage[48]={
 31, 0, 1, 2, 3, 4,
 3, 4, 5, 6, 7, 8,
 7, 8, 9, 10, 11, 12,
 11, 12, 13, 14, 15, 16,
 15, 16, 17, 18, 19, 20,
 19, 20, 21, 22, 23, 24,
 23, 24, 25, 26, 27, 28,
 27, 28, 29, 30, 31, 0};

int change[32]={
    15,  6, 19, 20,
 28, 11, 27, 16,
     0, 14, 22, 25,
  4, 17, 30,  9,
  1,  7, 23, 13,
 31, 26,  2,  8,
 18, 12, 29,  5,
 21, 10,  3, 24};

/*移位次数*/
int lstime[16]={
 1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};

/*pc-1*/
static unsigned char 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 };

/*pc-1*/
static unsigned char 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 };

static unsigned char s1[4][16] = {
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 };

/* Table - s2 */
static unsigned char s2[4][16] = {
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 };

/* Table - s3 */
static unsigned char s3[4][16] = {
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 };

/* Table - s4 */
static unsigned char s4[4][16] = {
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 };

/* Table - s5 */
static unsigned char s5[4][16] = {
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 };

/* Table - s6 */
static unsigned char s6[4][16] = {
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 };

/* Table - s7 */
static unsigned char s7[4][16] = {
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 };

/* Table - s8 */
static unsigned char s8[4][16] = {
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 };

void CDes::SetKey(const char* key)
{
 strcpy(this->m_strkey,key);
}

char* CDes::Encipher(const char* plain)
{
 int i,j,t,s,w,T;
 SAFE_DELARRAY(m_pOut);
 m_pOut = new char[65];
 for(i=0;i<=7;i++)
 {
  t=m_strkey[i];
  s=plain[i];
  for(j=0;j<=7;j++)
  {
   e1key[i*8+7-j]=t%2;
   bitpl[i*8+7-j]=s%2;
   t/=2;
   s/=2;
  }
 }

 IP1();

 for(i=0;i<32;i++)   //初始化左部
  left[i]=bitpl[i];

 for(i=32;i<64;i++)  //初始化右部
  right[i-32]=bitpl[i];

 for(i=0;i<56;i++)
  e2key[i]=e1key[pc1[i]];

 for(T=0;T<16;T++)  //循环16次
 {
  lst(lstime[T]);
  for(i=0;i<32;i++)
   brige[i]=right[i];  //复制一份右部
  
  for(i=0;i<48;i++)
      fkey[i]=e2key[pc2[i]]; //由56产生48密钥

  //拓展右部
  for(i=0;i<48;i++){
   large[i]=right[lage[i]];
   large[i]^=fkey[i];
  }

  //s盒替换
  i=0;    //s1
  s=(large[i]<<1)+large[i+5];
  t=(large[i+1]<<3)+(large[i+2]<<2)+(large[i+3]<<1)+large[i+4];
  w=s1[s][t];

  for(j=0;j<4;j++)
  {
   zhong[i/6*4+3-j]=w%2;
   w/=2;
  }

  i=6;    //s2
  s=(large[i]<<1)+large[i+5];
  t=(large[i+1]<<3)+(large[i+2]<<2)+(large[i+3]<<1)+large[i+4];
  w=s2[s][t];
  for(j=0;j<4;j++)
  {
   zhong[i/6*4+3-j]=w%2;
   w/=2;
  }

  i=12;    //s3
  s=(large[i]<<1)+large[i+5];
  t=(large[i+1]<<3)+(large[i+2]<<2)+(large[i+3]<<1)+large[i+4];
  w=s3[s][t];
  for(j=0;j<4;j++)
  {
   zhong[i/6*4+3-j]=w%2;
   w/=2;
  }

  i=18;    //s4
  s=(large[i]<<1)+large[i+5];
  t=(large[i+1]<<3)+(large[i+2]<<2)+(large[i+3]<<1)+large[i+4];
  w=s4[s][t];
  for(j=0;j<4;j++)
  {
   zhong[i/6*4+3-j]=w%2;
   w/=2;
  }

  i=24;   //s5
  s=(large[i]<<1)+large[i+5];
  t=(large[i+1]<<3)+(large[i+2]<<2)+(large[i+3]<<1)+large[i+4];
  w=s5[s][t];
  for(j=0;j<4;j++)
  {
   zhong[i/6*4+3-j]=w%2;
   w/=2;
  }

  i=30;   //s6
  s=(large[i]<<1)+large[i+5];
  t=(large[i+1]<<3)+(large[i+2]<<2)+(large[i+3]<<1)+large[i+4];
  w=s6[s][t];
  for(j=0;j<4;j++)
  {
   zhong[i/6*4+3-j]=w%2;
   w/=2;
  }

  i=36;   //s7
  s=(large[i]<<1)+large[i+5];
  t=(large[i+1]<<3)+(large[i+2]<<2)+(large[i+3]<<1)+large[i+4];
  w=s7[s][t];
  for(j=0;j<4;j++)
  {
   zhong[i/6*4+3-j]=w%2;
   w/=2;
  }

  i=42;   //s8
  s=(large[i]<<1)+large[i+5];
  t=(large[i+1]<<3)+(large[i+2]<<2)+(large[i+3]<<1)+large[i+4];
  w=s8[s][t];
  for(j=0;j<4;j++)
  {
   zhong[i/6*4+3-j]=w%2;
   w/=2;
  }

  //p盒置换,异或得到R(i+1)
  for(i=0;i<32;i++){
   right[i]=zhong[change[i]];
   right[i]^=left[i];
   left[i]=brige[i];
  }
    }
 for(i=0;i<32;i++)
  bitci[i]=right[i];
 for(i=0;i<32;i++)
  bitci[i+32]=left[i];
 IP2();
 for(i=0;i<64;i++)
  m_pOut[i]='0'+bitci[i];
 m_pOut[i]='\0';
 return m_pOut;
}

char* CDes::Decipher(const char* cipher)
{
 int i,j,t,s,w,T;
 SAFE_DELARRAY(m_pOut);
 m_pOut = new char[strlen(cipher)+1];
 for(i=0;i<=7;i++)
 {
  t=m_strkey[i];
  for(j=0;j<=7;j++)
  {
   e1key[i*8+7-j]=t%2;
   t/=2;
  }
 }

 for(i=0;i<64;i++)
  bitpl[i]=cipher[i]-'0';

 IP1();

 for(i=0;i<32;i++)   //初始化左部
  left[i]=bitpl[i];

 for(i=32;i<64;i++)  //初始化右部
  right[i-32]=bitpl[i];

 for(i=0;i<56;i++)
  e2key[i]=e1key[pc1[i]];

 for(i=0;i<16;i++)
  lst(lstime[i]);
 for(T=0;T<16;T++)  //循环16次
 {
  for(i=0;i<32;i++)
   brige[i]=right[i];  //复制一份右部
  
  for(i=0;i<48;i++)
      fkey[i]=e2key[pc2[i]]; //由56产生48密钥

  //拓展右部
  for(i=0;i<48;i++){
   large[i]=right[lage[i]];
   large[i]^=fkey[i];
  }
   
  //s盒替换
  i=0;    //s1
  s=(large[i]<<1)+large[i+5];
  t=(large[i+1]<<3)+(large[i+2]<<2)+(large[i+3]<<1)+large[i+4];
  w=s1[s][t];
  for(j=0;j<4;j++)
  {
   zhong[i/6*4+3-j]=w%2;
   w/=2;
  }

  i=6;    //s2
  s=(large[i]<<1)+large[i+5];
  t=(large[i+1]<<3)+(large[i+2]<<2)+(large[i+3]<<1)+large[i+4];
  w=s2[s][t];
  for(j=0;j<4;j++)
  {
   zhong[i/6*4+3-j]=w%2;
   w/=2;
  }

  i=12;    //s3
  s=(large[i]<<1)+large[i+5];
  t=(large[i+1]<<3)+(large[i+2]<<2)+(large[i+3]<<1)+large[i+4];
  w=s3[s][t];
  for(j=0;j<4;j++)
  {
   zhong[i/6*4+3-j]=w%2;
   w/=2;
  }

  i=18;    //s4
  s=(large[i]<<1)+large[i+5];
  t=(large[i+1]<<3)+(large[i+2]<<2)+(large[i+3]<<1)+large[i+4];
  w=s4[s][t];
  for(j=0;j<4;j++)
  {
   zhong[i/6*4+3-j]=w%2;
   w/=2;
  }

  i=24;   //s5
  s=(large[i]<<1)+large[i+5];
  t=(large[i+1]<<3)+(large[i+2]<<2)+(large[i+3]<<1)+large[i+4];
  w=s5[s][t];
  for(j=0;j<4;j++)
  {
   zhong[i/6*4+3-j]=w%2;
   w/=2;
  }

  i=30;   //s6
  s=(large[i]<<1)+large[i+5];
  t=(large[i+1]<<3)+(large[i+2]<<2)+(large[i+3]<<1)+large[i+4];
  w=s6[s][t];
  for(j=0;j<4;j++)
  {
   zhong[i/6*4+3-j]=w%2;
   w/=2;
  }

  i=36;   //s7
  s=(large[i]<<1)+large[i+5];
  t=(large[i+1]<<3)+(large[i+2]<<2)+(large[i+3]<<1)+large[i+4];
  w=s7[s][t];
  for(j=0;j<4;j++)
  {
   zhong[i/6*4+3-j]=w%2;
   w/=2;
  }

  i=42;   //s8
  s=(large[i]<<1)+large[i+5];
  t=(large[i+1]<<3)+(large[i+2]<<2)+(large[i+3]<<1)+large[i+4];
  w=s8[s][t];
  for(j=0;j<4;j++)
  {
   zhong[i/6*4+3-j]=w%2;
   w/=2;
  }

  //p盒置换,异或得到R(i+1)
  for(i=0;i<32;i++){
   right[i]=zhong[change[i]];
   right[i]^=left[i];
   left[i]=brige[i];
  }
  rst(lstime[15-T]);
 }
 for(i=0;i<32;i++)
  bitci[i]=right[i];
 for(i=0;i<32;i++)
  bitci[i+32]=left[i];
 IP2();
 w=0;
 for(i=0;i<64;i++){
  w=(w<<1)+bitci[i];
  if(i%8==7)
  {
   m_pOut[i/8]=w;
   w=0;
  }
 }
 m_pOut[8]='\0';
 return m_pOut;
}

void CDes::ls1()   //左移1位
{
 int t,i;
 t=e2key[0];
 for(i=0;i<=26;i++)
  e2key[i]=e2key[i+1];
 e2key[27]=t;
 t=e2key[28];
 for(i=28;i<=54;i++)
  e2key[i]=e2key[i+1];
 e2key[55]=t;
}

void CDes::rs1()  //右移1位
{
 int t,i;
 t=e2key[27];
 for(i=27;i>0;i--)
  e2key[i]=e2key[i-1];
 e2key[0]=t;
 t=e2key[55];
 for(i=55;i>28;i--)
  e2key[i]=e2key[i-1];
 e2key[28]=t;
}

void CDes::lst(int time)
{
 int i;
 for(i=1;i<=time;i++)
  ls1();
}

void CDes::rst(int time)
{
 int i;
 for(i=1;i<=time;i++)
  rs1();
}

void CDes::IP1()
{
 int i;
 for(i=0;i<64;i++)
  bitip[i]=bitpl[ip1[i]];
 for(i=0;i<64;i++)
  bitpl[i]=bitip[i];
}

void CDes::IP2()
{
 int i;
 for(i=0;i<64;i++)
  bitip[i]=bitci[ip2[i]];
 for(i=0;i<64;i++)
  bitci[i]=bitip[i];
}


///CIdea/
CIdea::CIdea()
{

}

CIdea::~CIdea()
{

}

/* 两数相加,模65536 */
WORD CIdea::Addition(WORD x, WORD y)
{
 return ( x + y ) ;
}

/* 两数相乘,模65537 */
WORD CIdea::Multi(WORD x, WORD y)
{
 if ( ! x && ! y )
  return 0 ;
 else if ( ! x )
  return ( WORD ) ( (  y * CARDINALITY ) % ( CARDINALITY + 1 ) ) ;         
 else if ( ! y )
  return ( WORD ) ( (  x * CARDINALITY ) % ( CARDINALITY + 1 ) ) ;         
 else
  return ( WORD ) ( ( ( DWORD ) x * y ) % ( CARDINALITY + 1 ) ) ;         
}

/* 利用辗转相除法,求一个数模65537的逆 */
WORD CIdea::Inverse(WORD x)
{
 DWORD dwQuotient ;        // 商
 DWORD dwResidual ;        // 余
 DWORD dwDividend = CARDINALITY + 1 ;       // 被除数
 DWORD dwDivisor = ( DWORD ) x ;     // 除数
 DWORD dwResult ;            // 结果
 DWORD dwValue1 = 1 , dwValue2 ;     // 中间值 
 
 if ( x <=1 )
  return x ;
 dwResult = dwValue2 = dwDividend / dwDivisor ;
 dwResidual = dwDividend % dwDivisor ;
 dwDividend = dwDivisor ;
 dwDivisor = dwResidual ;
 dwQuotient = dwDividend / dwDivisor ;
 dwResidual = dwDividend % dwDivisor ;
 while ( dwResidual )
 {
  dwResult = dwQuotient * dwValue2 + dwValue1 ;
  dwValue1 = dwValue2 ;
  dwValue2 = dwResult ;
  dwDividend = dwDivisor ;
  dwDivisor = dwResidual ;
  dwQuotient = dwDividend / dwDivisor ;
  dwResidual = dwDividend % dwDivisor ;
 }
 if ( ( ( dwResult * x ) % ( CARDINALITY + 1 ) ) == CARDINALITY )
 {
  int nModular = - ( int ) dwResult ;
  while ( ( nModular += ( CARDINALITY + 1 ) ) <= 0 ) ;
  dwResult = nModular ;
 }
 return ( WORD ) dwResult ;
}

/* 循环左移25位,生成一组密钥子块 */
void CIdea::GenSubKey( )
{
 WORD wSave , wTemp ;
 WORD * pwShift = wKeySeed ;
 short sPos ;

 wSave = pwShift [ 0 ] ;
 wTemp = pwShift [ 1 ] ;
 for ( sPos = 1 ; sPos < ROUND - 1; sPos ++ )
 {
  pwShift [ sPos - 1 ] = ( pwShift [ sPos ]  << 9 ) | ( pwShift [ sPos + 1 ] >> 7 ) ;
 }
    pwShift [ sPos - 1 ] = ( pwShift [ sPos ] << 9 ) | ( wSave >> 7 ) ;
 pwShift [ sPos ] = ( wSave << 9 ) | ( wTemp >> 7 ) ;
}

/* 生成加密密钥*/
void CIdea::GenEncryptKey( )
{
 short sTimes , sPos , sLength = ROUND ;
 
 for ( sPos = 0 ; sPos < sLength ; sPos ++ )
 {
  pwEncryptKey [ sPos ] = wKeySeed [ sPos ] ;
 }
 for ( sTimes = 1 ; sTimes <= KEYSIZE ; sTimes ++ )
 {
  GenSubKey ( ) ;
  if ( KEYSIZE == sTimes )
   sLength = ROUND / 2 ;
  else
   sLength = ROUND ;
  for ( sPos = 0 ; sPos < sLength ; sPos ++ )
  {
   pwEncryptKey [ sTimes * ROUND + sPos ] = wKeySeed [ sPos ] ;
  }
 }
}

/* 生成解密密钥 */
void CIdea::GenDecryptKey( )
{
 short sTurn ;

 GenEncryptKey ( ) ;    // 生成加密密钥

 /* 由加密密钥生成解密密钥 */
 for ( sTurn = 0 ; sTurn < ROUND ; sTurn ++ )
 {
  /* 生成8轮迭代解密密钥 */
  pwDecryptKey [ sTurn * KEYSIZE ] = Inverse ( pwEncryptKey [ ( ROUND - sTurn ) * KEYSIZE ] ) ;
  if( sTurn )
  {
   pwDecryptKey [ sTurn * KEYSIZE + 1 ] = - pwEncryptKey [ ( ROUND - sTurn ) * KEYSIZE + 2 ] ;
   pwDecryptKey [ sTurn * KEYSIZE + 2 ] = - pwEncryptKey [ ( ROUND - sTurn ) * KEYSIZE + 1 ] ;
  }
  else
  {
   pwDecryptKey [ sTurn * KEYSIZE + 1 ] = - pwEncryptKey [ ( ROUND - sTurn ) * KEYSIZE + 1 ] ;
   pwDecryptKey [ sTurn * KEYSIZE + 2 ] = - pwEncryptKey [ ( ROUND - sTurn ) * KEYSIZE + 2 ] ;
  }

  pwDecryptKey [ sTurn * KEYSIZE + 3 ] = Inverse ( pwEncryptKey [ ( ROUND - sTurn ) * KEYSIZE + 3 ] ) ;
  pwDecryptKey [ sTurn * KEYSIZE + 4 ] = pwEncryptKey [ ( ROUND - 1 - sTurn ) * KEYSIZE + 4 ] ;
  pwDecryptKey [ sTurn * KEYSIZE + 5 ] = pwEncryptKey [ ( ROUND - 1 - sTurn ) * KEYSIZE + 5 ] ;

 }

 /* 生成输出密钥 */
 pwDecryptKey [ sTurn * KEYSIZE     ] = Inverse ( pwEncryptKey [ 0 ] );
 pwDecryptKey [ sTurn * KEYSIZE + 1 ] = - pwEncryptKey [ 1 ] ;
 pwDecryptKey [ sTurn * KEYSIZE + 2 ] = - pwEncryptKey [ 2 ] ;
 pwDecryptKey [ sTurn * KEYSIZE + 3 ] = Inverse ( pwEncryptKey [ 3 ] );
}

/* 单轮迭代 */
void CIdea::Iteration( short sTurn , bool bCrypt )
{
 short sPos ;
 WORD wSubKey [ KEYSIZE ];
 WORD wMidValue [ 10 ] ;
 WORD * pwKey , * wInputText , * wOutputText;
 
 if ( bCrypt )
 {
  wInputText = wPlain ;
  pwKey = pwEncryptKey ;
  wOutputText = wCipher ;
 }
 else
 {
  wInputText = wCipher ;
  pwKey = pwDecryptKey ;
  wOutputText = wPlain ;
 }
 if ( sTurn < ROUND )
 {
  for ( sPos = 0 ; sPos < KEYSIZE ; sPos ++ )
  {
   wSubKey [ sPos ] = pwKey [ sTurn * KEYSIZE + sPos ] ;
  }
  wMidValue [ 0 ] = Multi ( wInputText [ 0 ] ,wSubKey [ 0 ] ) ;
  wMidValue [ 1 ] = Addition ( wInputText [ 1 ] , wSubKey [ 1 ] ) ;
  wMidValue [ 2 ] = Addition ( wInputText [ 2 ] , wSubKey [ 2 ] ) ;
  wMidValue [ 3 ] = Multi ( wInputText [ 3 ] ,wSubKey [ 3 ] ) ;
  wMidValue [ 4 ] = wMidValue [ 0 ] ^ wMidValue [ 2 ] ;
  wMidValue [ 5 ] = wMidValue [ 1 ] ^ wMidValue [ 3 ] ;
  wMidValue [ 6 ] = Multi ( wMidValue [ 4 ] , wSubKey [ 4 ] ) ;
  wMidValue [ 7 ] = Addition ( wMidValue [ 5 ] , wMidValue [ 6 ] ) ;
  wMidValue [ 8 ] = Multi ( wMidValue [ 7 ] , wSubKey [ 5 ] ) ;
  wMidValue [ 9 ] = Addition ( wMidValue [ 6 ] , wMidValue [ 8 ] ) ;
  
  /* 单轮输出 */
  wInputText [ 0 ] = wMidValue [ 0 ] ^ wMidValue [ 8 ] ;
  wInputText [ 1 ] = wMidValue [ 2 ] ^ wMidValue [ 8 ] ;
  wInputText [ 2 ] = wMidValue [ 1 ] ^ wMidValue [ 9 ] ;
  wInputText [ 3 ] = wMidValue [ 3 ] ^ wMidValue [ 9 ] ;
 }
 else
 {
  /* 最后输出子块 */
  for ( sPos = 0 ; sPos < ROUND / 2 ; sPos ++ )
  {
   wSubKey [ sPos ] = pwKey [ sTurn * KEYSIZE + sPos ] ;
  }
  wOutputText [ 0 ] = Multi ( wInputText [ 0 ] , wSubKey [ 0 ] ) ;
  wOutputText [ 1 ] = Addition ( wInputText [ 2 ] , wSubKey [ 1 ] ) ;
  wOutputText [ 2 ] = Addition ( wInputText [ 1 ] , wSubKey [ 2 ] ) ;
  wOutputText [ 3 ] = Multi ( wInputText [ 3 ] , wSubKey [ 3 ] ) ;
 }
}


/* 对一组明文块进行加密 */
void CIdea::Encipher( )
{
 short sTurn ;
 for ( sTurn = 0 ; sTurn <= ROUND ; sTurn ++ )
  Iteration  ( sTurn , true ) ;
}

/* 对一组密文块进行解密 */
void CIdea::Decipher( )
{
 short sTurn ;
 for ( sTurn = 0 ; sTurn <= ROUND ; sTurn ++ )
  Iteration  ( sTurn , false ) ;   // 单轮迭代
}

void CIdea::SetNewKey( WORD * KeySeed)
{
 for( int i = 0; i < ROUND; i ++ )
 {
  wKeySeed[ i ] = KeySeed[ i ];
 }
 GenDecryptKey( );
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
md5 用c++实现md5算法. 开发平台 Ubuntu14.04 运行 sudo get-apt install g++ make ./md5_test md5简介 消息摘要算法第五版(英语:Message-Digest Algorithm 5,缩写为MD5),是当前计算机领域用于确保信息传输完整一致而广泛使用的散列算法之一(又译哈希算法、摘要算法等),主流编程语言普遍已有MD5的实现。将数据 (如一段文字)运算变为另一固定长度值,是散列算法的基础原理,MD5的前身有MD2、MD3和MD4。MD5由MD4、MD3、MD2改进而来,主要增强算法复杂度和不可逆性。目前,MD5算法因其普遍、稳定、快速的特点,仍广泛应用于普通 数据的错误检查领域。例如在一些BitTorrent下载中,软件将通过计算MD5检验下载到的文件片段的完整性。MD5已经广泛使用在为文件传输提供一定的可靠性方面。例如,服务器预先提供一个MD5校验和,用户下载完文件以后, 用MD5算法计算下载文件的MD5校验和,然后通过检查这两个校验和是否一致,就能判断下载的文件是否出错。MD5是输入不定长度信息,输出固定长度128-bits的算法。经过程序流程,生成四个32位数据,最后联合起来成为一个 128-bits散列。基本方式为,求余、取余、调整长度、与链接变量进行循环运算。得出结果。 md5算法描述 假设输入信息(input message)的长度为b(bit),我们想要产生它的报文摘要,在此处b为任意的非负整数:b也可能为0,也不一定为8的整数倍,且可能是任意大的长度。设该信息的比特流表示如下: M[0] M[1] M[2] ... M[b-1] 计算此信息的报文摘要需要如下5步: 1.补位 信息计算前先要进行位补位,设补位后信息的长度为LEN(bit),则LEN%512 = 448(bit),即数据扩展至 K * 512 + 448(bit)。即K * 64+56(byte),K为整数。补位操作始终要执行,即使补位前信息的长度对512求余的结果是448。具体补位操作:补一个1,然后补0至满足上述要求。总共最少要补1bit,最多补512bit。 2.尾部加上信息长度 将输入信息的原始长度b(bit)表示成一个64-bit的数字,把它添加到上一步的结果后面(在32位的机器上,这64位将用2个字来表示并且低位在前)。当遇到b大于2^64这种极少的情况时,b的高位被截去,仅使用b的低64位。经过上面两步,数据就被填补成长度为512(bit)的倍数。也就是说,此时的数据长度是16个字(32byte)的整数倍。此时的数据表示为: M[0 ... N-1] 其中的N是16的倍数。 3.初始化缓存区 用一个四个字的缓冲器(A,B,C,D)来计算报文摘要,A,B,C,D分别是32位的寄存器,初始化使用的是十六进制表示的数字,注意低字节在前: word A: 01 23 45 67 word B: 89 ab cd ef word C: fe dc ba 98 word D: 76 54 32 10 4.转换 首先定义4个辅助函数,每个函数的输入是三个32位的字,输出是一个32位的字: F(X,Y,Z) = XY v not(X) Z G(X,Y,Z) = XZ v Y not(Z) H(X,Y,Z) = X xor Y xor Z I(X,Y,Z) = Y xor (X v not(Z)) FF(a,b,c,d,Mj,s,ti)表示 a = b + ((a + F(b,c,d) + Mj + ti) << s) GG(a,b,c,d,Mj,s,ti)表示 a = b + ((a + G(b,c,d) + Mj + ti) << s) HH(a,b,c,d,Mj,s,ti)表示 a = b + ((a + H(b,c,d) + Mj + ti) << s) Ⅱ(a,b,c,d,Mj,s,ti)表示 a = b + ((a + I(b,c,d) + Mj + ti) << s) 这四轮(64步)是: 第一轮 FF(a,b,c,d,M0,7,0xd76aa478) FF(d,a,b,c,M1,12,0xe8c7b756) FF(c,d,a,b,M2,17,0x242070db) FF(b,c,d,a,M3,22,0xc1bdceee) FF(a,b,c,d,M4,7,0xf57c0faf) FF(d,a,b,c,M5,12,0x4787c62a) FF(c,d,a,b,M6,17,0xa8304613) FF(b,c,d,a,M7,22,0xfd469501) FF(a,b,c,d,M8,7,0x698098d8) FF(d,a,b,c,M9,12,0x8b44f7af) FF(c,d,a,b,M10,17,0xffff5bb1) FF(b,c,d,a,M11,22,0x895cd7be) FF(a,b,c,d,M12,7,0x6b901122) FF(d,a,b,c,M13,12,0xfd987193) FF(c,d,a,b,M14,17,0xa679438e) FF(b,c,d,a,M15,22,0x49b40821) 第二轮 GG(a,b,c,d,M1,5,0xf61e2562) GG(d,a,b,c,M6,9,0xc040b340) GG(c,d,a,b,M11,14,0x265e5a51) GG(b,c,d,a,M0,20,0xe9b6c7aa) GG(a,b,c,d,M5,5,0xd62f105d) GG(d,a,b,c,M10,9,0x02441453) GG(c,d,a,b,M15,14,0xd8a1e681) GG(b,c,d,a,M4,20,0xe7d3fbc8) GG(a,b,c,d,M9,5,0x21e1cde6) GG(d,a,b,c,M14,9,0xc33707d6) GG(c,d,a,b,M3,14,0xf4d50d87) GG(b,c,d,a,M8,20,0x455a14ed) GG(a,b,c,d,M13,5,0xa9e3e905) GG(d,a,b,c,M2,9,0xfcefa3f8) GG(c,d,a,b,M7,14,0x676f02d9) GG(b,c,d,a,M12,20,0x8d2a4c8a) 第三轮 HH(a,b,c,d,M5,4,0xfffa3942) HH(d,a,b,c,M8,11,0x8771f681) HH(c,d,a,b,M11,16,0x6d9d6122) HH(b,c,d,a,M14,23,0xfde5380c) HH(a,b,c,d,M1,4,0xa4beea44) HH(d,a,b,c,M4,11,0x4bdecfa9) HH(c,d,a,b,M7,16,0xf6bb4b60) HH(b,c,d,a,M10,23,0xbebfbc70) HH(a,b,c,d,M13,4,0x289b7ec6) HH(d,a,b,c,M0,11,0xeaa127fa) HH(c,d,a,b,M3,16,0xd4ef3085) HH(b,c,d,a,M6,23,0x04881d05) HH(a,b,c,d,M9,4,0xd9d4d039) HH(d,a,b,c,M12,11,0xe6db99e5) HH(c,d,a,b,M15,16,0x1fa27cf8) HH(b,c,d,a,M2,23,0xc4ac5665) 第四轮 Ⅱ(a,b,c,d,M0,6,0xf4292244) Ⅱ(d,a,b,c,M7,10,0x432aff97) Ⅱ(c,d,a,b,M14,15,0xab9423a7) Ⅱ(b,c,d,a,M5,21,0xfc93a039) Ⅱ(a,b,c,d,M12,6,0x655b59c3) Ⅱ(d,a,b,c,M3,10,0x8f0ccc92) Ⅱ(c,d,a,b,M10,15,0xffeff47d) Ⅱ(b,c,d,a,M1,21,0x85845dd1) Ⅱ(a,b,c,d,M8,6,0x6fa87e4f) Ⅱ(d,a,b,c,M15,10,0xfe2ce6e0) Ⅱ(c,d,a,b,M6,15,0xa3014314) Ⅱ(b,c,d,a,M13,21,0x4e0811a1) Ⅱ(a,b,c,d,M4,6,0xf7537e82) Ⅱ(d,a,b,c,M11,10,0xbd3af235) Ⅱ(c,d,a,b,M2,15,0x2ad7d2bb) Ⅱ(b,c,d,a,M9,21,0xeb86d391)

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值