首    页 界面/窗口 网络/通讯 数据库 组件开发 图像/多媒体 NET/Web 其它技术 源码下载 资料下载 软件共享 软件外包 曲艺杂谈
栏目导航:  首    页  |  其它技术  |  加密解密  


VC实现数据的加密和解密(MD5加密\DES\RSA加密解密)


原作者:不详    源出处:CSDN   发布者:施昌权    发布类型:转载    发布日期:2008-12-02


  

VC实现数据的加密和解密

由于生产实习的时间有限,加上自己这段时间致力于考研,因此,仅仅是实现了通过MD5\DES\RSA的简单的字符串的加密解密,希望有兴趣的兄弟姐妹能够完善它。

主要的程序如下:

1)、MD5

// MD5.h: interface for the CMD5 class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_MD5_H__EA6A200B_1336_43F3_B866_2A2E28D54560__INCLUDED_)
#define AFX_MD5_H__EA6A200B_1336_43F3_B866_2A2E28D54560__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

//测试判别:摘自http://www.ietf.org/rfc/rfc1321.txt
/*
MD5 ("") = d41d8cd98f00b204e9800998ecf8427e
MD5 ("a") = 0cc175b9c0f1b6a831c399e269772661
MD5 ("abc") = 900150983cd24fb0d6963f7d28e17f72
MD5 ("message digest") = f96b697d7cb7938d525a2f31aaf161d0
MD5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b
MD5 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") =
d174ab98d277d9f5a5611c2c9f419d9f
MD5 ("123456789012345678901234567890123456789012345678901234567890123456
78901234567890") = 57edf4a22be3c955ac49da2e2107b67a
*/
//补充MD5算法是不可逆的算法,也就是说不存在解密,惟有暴力解密才可以解密。 该算法主要是对摘要进行加密
//主要是用于用户口令的加密,例如:UNIX里面用户口令保存都是也MD5加密后进行存储,当用户登录时,首先要对输
//入的口令进行MD5进行加密,然后再和存储的MD5加密用户口令进行比较
#include <string>
using namespace std;

class CMD5
{
public:
  //CONSTRUCTOR
  CMD5();
  //对基类的虚函数进行实现
  void AddData(char const* pcData, int iDataLength);
  void FinalDigest(char* pcDigest);
  void Reset();
  void DigestFile(string const& readFile, char* pcDigest);
  virtual ~CMD5();
protected:
  //设置附上64位的消息长度
  enum { BLOCKSIZE=64 };
  BOOL m_bAddData;
private:
  //总共要经过4轮变换
  enum { MD128LENGTH=4 };
  //设定每次读取文件长度长度为1024位,数据长度为384(可以i自己设定)
  enum { DATA_LEN=384, BUFF_LEN=1024 };
  //四个32-位的变量,数值必须为正整数,就是A,B,C,D
  unsigned int m_auiBuf[4];
  unsigned int m_auiBits[2];
  //获取M0-〉M64消息的64个子分组
  unsigned char m_aucIn[64];

 //主循环要经过四轮变换,第一轮要经过16次操作,都是由下面的基本运算组成
  static unsigned int F(unsigned int x, unsigned int y, unsigned int z);
  static unsigned int G(unsigned int x, unsigned int y, unsigned int z);
  static unsigned int H(unsigned int x, unsigned int y, unsigned int z);
  static unsigned int I(unsigned int x, unsigned int y, unsigned int z);

 //对FF,GG,HH,II函数进行定义
  //具体的参数说明:第一个参数为:F1、F2、F3、F4方法的选择,第二个参数为:运算的结果,即初始化的参数
  //第三、四、五个参数为初始化的参数,具体为a,b,c,d中的不同的三个,第六个参数为:消息的第J个子分组,第七个参数为循环左移S位
  static void MD5STEP(unsigned int (*f)(unsigned int x, unsigned int y, unsigned int z),
   unsigned int& w, unsigned int x, unsigned int y, unsigned int z, unsigned int data, unsigned int s);
  //MD5四轮变换算法,具体是对四轮中的每一轮进行16次运算
  void MD5Transform();
};
//具体的函数可以参考http://www.ietf.org/rfc/rfc1321.txt,The MD5 Message-Digest Algorithm(MD5摘要加密算法)
//第一个非线性函数,即所谓的F函数:F(X,Y,Z) = (X&Y)|((~X)&Z)
inline unsigned int CMD5::F(unsigned int x, unsigned int y, unsigned int z)
{
  return (x & y | ~x & z);
}
//第二个非线性函数,即所谓的G函数:G(X,Y,Z) = (X&Z)|(Y&(~Z))
inline unsigned int CMD5::G(unsigned int x, unsigned int y, unsigned int z)
{
  return F(z, x, y);
}
//第三个非线性函数,即所谓的H函数:H(X,Y,Z) = X XOR Y XOR Z
inline unsigned int CMD5::H(unsigned int x, unsigned int y, unsigned int z)
{
  return x ^ y ^ z;
}
//第四个非线性函数,即所谓的I函数:I(X,Y,Z) = Y XOR (X | (~Z))
inline unsigned int CMD5::I(unsigned int x, unsigned int y, unsigned int z)
{
  return (y ^ (x | ~z));
}
//
inline void CMD5::MD5STEP(unsigned int (*f)(unsigned int x, unsigned int y, unsigned int z),
  unsigned int& w, unsigned int x, unsigned int y, unsigned int z, unsigned int data, unsigned int s)
{
  w += f(x, y, z) + data;
  w = w << s | w >> (32-s);
  w += x;
}
#endif // !defined(AFX_MD5_H__EA6A200B_1336_43F3_B866_2A2E28D54560__INCLUDED_)
// MD5.cpp: implementation of the CMD5 class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "EncryAndDecrypt.h"
#include "MD5.h"
#include "FileBuffer.h"
#include <fstream>
#include <strstream>

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

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//初始化变量值
CMD5::CMD5():m_bAddData(false)
{
  //对四个32位的变量进行初始化
  m_auiBuf[0] = 0x67452301;
  m_auiBuf[1] = 0xefcdab89;
  m_auiBuf[2] = 0x98badcfe;
  m_auiBuf[3] = 0x10325476;
  m_auiBits[0] = 0;
  m_auiBits[1] = 0;
}

CMD5::~CMD5()
{
}
void CMD5::AddData(char const* pcData, int iDataLength)
{
  if(iDataLength < 0)
   AfxMessageBox("MD5文件加密失败!,数据的长度必须大于0");
  unsigned int uiT;
  //更新位长度
  uiT = m_auiBits[0];
  //参考MD5Update函数
  if((m_auiBits[0] = uiT + ((unsigned int)iDataLength << 3)) < uiT)
   m_auiBits[1]++;
  m_auiBits[1] += iDataLength >> 29;
  uiT = (uiT >> 3) & (BLOCKSIZE-1); //转化为字节
  //处理奇数块
  if(uiT != 0)
  {
   unsigned char *puc = (unsigned char *)m_aucIn + uiT;
   uiT = BLOCKSIZE - uiT;
   if(iDataLength < uiT)
   {
    memcpy(puc, pcData, iDataLength);
    return;
   }
   memcpy(puc, pcData, uiT);
   MD5Transform();
   pcData += uiT;
   iDataLength -= uiT;
  }
  //处理长度为64字节数据块
  while(iDataLength >= BLOCKSIZE)
  {
   memcpy(m_aucIn, pcData, BLOCKSIZE);
   MD5Transform();
   pcData += BLOCKSIZE;
   iDataLength -= BLOCKSIZE;
  }
  //处理余下的数据
  memcpy(m_aucIn, pcData, iDataLength);
  //设置标志位
  m_bAddData = true;
}
void CMD5::FinalDigest(char* pcDigest)
{
  if(m_bAddData == false)
   AfxMessageBox("MD5文件加密失败!,没有数据被添加");
  unsigned int uiCount;
  unsigned char* puc;
  //参考MD5Update函数
  //计算字节对64取余运算
  uiCount = (m_auiBits[0] >> 3) & (BLOCKSIZE-1);
  //参考static unsigned char PADDING[64]~~即对对一个填充位设置为0x80
  puc = m_aucIn + uiCount;
  *puc++ = 0x80;
  //同时要通过填充来达到64个字节
  uiCount = BLOCKSIZE - uiCount - 1;
  //填充到64位长度
  //假如填充的长度未达到64位长度
  if(uiCount < 8)
  {
   //首先要填充前面64个字节
   memset(puc, 0, uiCount);
   MD5Transform();
   //然后要填充后面的56个字节
   memset(m_aucIn, 0, BLOCKSIZE-8);
  }
  //已经达到64位
  else
  {
   //直接填充56个字节
   memset(puc, 0, uiCount - 8);
  }
  //添加位长度同时进行MD5变换
  ((unsigned int*)m_aucIn)[(BLOCKSIZE>>2)-2] = m_auiBits[0];
  ((unsigned int*)m_aucIn)[(BLOCKSIZE>>2)-1] = m_auiBits[1];
  MD5Transform();
  memcpy(pcDigest, m_auiBuf, MD128LENGTH<<2);
  //重新设置大小
  Reset();
}
void CMD5::Reset()
{
  //对四个32位的变量重新设置
  m_auiBuf[0] = 0x67452301;
  m_auiBuf[1] = 0xefcdab89;
  m_auiBuf[2] = 0x98badcfe;
  m_auiBuf[3] = 0x10325476;
  m_auiBits[0] = 0;
  m_auiBits[1] = 0;
  //重设标志
  m_bAddData = false;
}

//MD5四轮变换算法,具体的64次运算过程如下
void CMD5::MD5Transform()
{
  unsigned int* puiIn = (unsigned int*)m_aucIn;
  register unsigned int a, b, c, d;
  a = m_auiBuf[0];
  b = m_auiBuf[1];
  c = m_auiBuf[2];
  d = m_auiBuf[3];
  //第一轮
  MD5STEP(F, a, b, c, d, puiIn[0] + 0xd76aa478, 7);
  MD5STEP(F, d, a, b, c, puiIn[1] + 0xe8c7b756, 12);
  MD5STEP(F, c, d, a, b, puiIn[2] + 0x242070db, 17);
  MD5STEP(F, b, c, d, a, puiIn[3] + 0xc1bdceee, 22);
  MD5STEP(F, a, b, c, d, puiIn[4] + 0xf57c0faf, 7);
  MD5STEP(F, d, a, b, c, puiIn[5] + 0x4787c62a, 12);
  MD5STEP(F, c, d, a, b, puiIn[6] + 0xa8304613, 17);
  MD5STEP(F, b, c, d, a, puiIn[7] + 0xfd469501, 22);
  MD5STEP(F, a, b, c, d, puiIn[8] + 0x698098d8, 7);
  MD5STEP(F, d, a, b, c, puiIn[9] + 0x8b44f7af, 12);
  MD5STEP(F, c, d, a, b, puiIn[10] + 0xffff5bb1, 17);
  MD5STEP(F, b, c, d, a, puiIn[11] + 0x895cd7be, 22);
  MD5STEP(F, a, b, c, d, puiIn[12] + 0x6b901122, 7);
  MD5STEP(F, d, a, b, c, puiIn[13] + 0xfd987193, 12);
  MD5STEP(F, c, d, a, b, puiIn[14] + 0xa679438e, 17);
  MD5STEP(F, b, c, d, a, puiIn[15] + 0x49b40821, 22);
  //第二轮
  MD5STEP(G, a, b, c, d, puiIn[1] + 0xf61e2562, 5);
  MD5STEP(G, d, a, b, c, puiIn[6] + 0xc040b340, 9);
  MD5STEP(G, c, d, a, b, puiIn[11] + 0x265e5a51, 14);
  MD5STEP(G, b, c, d, a, puiIn[0] + 0xe9b6c7aa, 20);
  MD5STEP(G, a, b, c, d, puiIn[5] + 0xd62f105d, 5);
  MD5STEP(G, d, a, b, c, puiIn[10] + 0x02441453, 9);
  MD5STEP(G, c, d, a, b, puiIn[15] + 0xd8a1e681, 14);
  MD5STEP(G, b, c, d, a, puiIn[4] + 0xe7d3fbc8, 20);
  MD5STEP(G, a, b, c, d, puiIn[9] + 0x21e1cde6, 5);
  MD5STEP(G, d, a, b, c, puiIn[14] + 0xc33707d6, 9);
  MD5STEP(G, c, d, a, b, puiIn[3] + 0xf4d50d87, 14);
  MD5STEP(G, b, c, d, a, puiIn[8] + 0x455a14ed, 20);
  MD5STEP(G, a, b, c, d, puiIn[13] + 0xa9e3e905, 5);
  MD5STEP(G, d, a, b, c, puiIn[2] + 0xfcefa3f8, 9);
  MD5STEP(G, c, d, a, b, puiIn[7] + 0x676f02d9, 14);
  MD5STEP(G, b, c, d, a, puiIn[12] + 0x8d2a4c8a, 20);
  //第三轮
  MD5STEP(H, a, b, c, d, puiIn[5] + 0xfffa3942, 4);
  MD5STEP(H, d, a, b, c, puiIn[8] + 0x8771f681, 11);
  MD5STEP(H, c, d, a, b, puiIn[11] + 0x6d9d6122, 16);
  MD5STEP(H, b, c, d, a, puiIn[14] + 0xfde5380c, 23);
  MD5STEP(H, a, b, c, d, puiIn[1] + 0xa4beea44, 4);
  MD5STEP(H, d, a, b, c, puiIn[4] + 0x4bdecfa9, 11);
  MD5STEP(H, c, d, a, b, puiIn[7] + 0xf6bb4b60, 16);
  MD5STEP(H, b, c, d, a, puiIn[10] + 0xbebfbc70, 23);
  MD5STEP(H, a, b, c, d, puiIn[13] + 0x289b7ec6, 4);
  MD5STEP(H, d, a, b, c, puiIn[0] + 0xeaa127fa, 11);
  MD5STEP(H, c, d, a, b, puiIn[3] + 0xd4ef3085, 16);
  MD5STEP(H, b, c, d, a, puiIn[6] + 0x04881d05, 23);
  MD5STEP(H, a, b, c, d, puiIn[9] + 0xd9d4d039, 4);
  MD5STEP(H, d, a, b, c, puiIn[12] + 0xe6db99e5, 11);
  MD5STEP(H, c, d, a, b, puiIn[15] + 0x1fa27cf8, 16);
  MD5STEP(H, b, c, d, a, puiIn[2] + 0xc4ac5665, 23);
  //第四轮
  MD5STEP(I, a, b, c, d, puiIn[0] + 0xf4292244, 6);
  MD5STEP(I, d, a, b, c, puiIn[7] + 0x432aff97, 10);
  MD5STEP(I, c, d, a, b, puiIn[14] + 0xab9423a7, 15);
  MD5STEP(I, b, c, d, a, puiIn[5] + 0xfc93a039, 21);
  MD5STEP(I, a, b, c, d, puiIn[12] + 0x655b59c3, 6);
  MD5STEP(I, d, a, b, c, puiIn[3] + 0x8f0ccc92, 10);
  MD5STEP(I, c, d, a, b, puiIn[10] + 0xffeff47d, 15);
  MD5STEP(I, b, c, d, a, puiIn[1] + 0x85845dd1, 21);
  MD5STEP(I, a, b, c, d, puiIn[8] + 0x6fa87e4f, 6);
  MD5STEP(I, d, a, b, c, puiIn[15] + 0xfe2ce6e0, 10);
  MD5STEP(I, c, d, a, b, puiIn[6] + 0xa3014314, 15);
  MD5STEP(I, b, c, d, a, puiIn[13] + 0x4e0811a1, 21);
  MD5STEP(I, a, b, c, d, puiIn[4] + 0xf7537e82, 6);
  MD5STEP(I, d, a, b, c, puiIn[11] + 0xbd3af235, 10);
  MD5STEP(I, c, d, a, b, puiIn[2] + 0x2ad7d2bb, 15);
  MD5STEP(I, b, c, d, a, puiIn[9] + 0xeb86d391, 21);
  //将ABCD分别加上abcd,
  m_auiBuf[0] += a;
  m_auiBuf[1] += b;
  m_auiBuf[2] += c;
  m_auiBuf[3] += d;
}

void CMD5::DigestFile(string const& readFile, char* pcDigest)
{
  //以二进制的形式打开文件中的内容
  ifstream Readin(readFile.c_str(), ios::binary);
  if(!Readin)//打开失败
  {
   ostrstream ostr;
   ostr<<"打开加密文件失败!"<<endl;
  }
  //打开文件成功
  Reset();
  //开始读取文件
  char szLargeBuff[BUFF_LEN+1] = {0};
  char szBuff[DATA_LEN+1] = {0};
  //开始读取数据
  CFileBuffer fileRead(Readin, szLargeBuff, BUFF_LEN, DATA_LEN);
  int iRead;
  //一直读取数据
  while((iRead = fileRead.GetData(szBuff)) > 0)
   AddData(szBuff, iRead);
  //关闭文件
  Readin.close();
  //对文件进行最后一步进行加密
  FinalDigest(pcDigest);
}
2)、RSA:

// RSA.h: interface for the CRSA class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_RSA_H__A0CC2413_F410_45CE_911B_7A21D7A5155B__INCLUDED_)
#define AFX_RSA_H__A0CC2413_F410_45CE_911B_7A21D7A5155B__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class CEncryAndDecryptDlg;
class CRSA 
{
public:
  CString Encrypt(CString szMessage, int p, int q,int e);
  CString Decrypt(CString szMessage,int e,int n);
  int  GetSecretKey(int p, int q);
  CRSA();
  virtual ~CRSA();
private:
  BOOL IsPrime(int x);
  int  GetValues(int iMessage,int d,int n);
  //求模逆元运算
  void ExtBinEuclid(int* u,int* v,int* u1,int* u2,int* u3);

};

#endif // !defined(AFX_RSA_H__A0CC2413_F410_45CE_911B_7A21D7A5155B__INCLUDED_)
// RSA.cpp: implementation of the CRSA class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "EncryAndDecrypt.h"
#include "RSA.h"
#include <math.h>
#include <string.h>
#include "EncryAndDecryptDlg.h"

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

#define isEven(x) ((x&0x01) == 0)
#define isOdd(x) (x&0x01)
#define swap(x,y) (x ^= y,y ^= x,x ^= y)

CRSA::CRSA()
{

}

CRSA::~CRSA()
{

}

//对szMessage利用RSA算法进行测试
CString CRSA::Encrypt(CString szMessage, int p, int q,int e)
{
  int t,d,n,iMessage,EncryValues,a,b,gcd;
  CString EncryMessage;
  n = p*q;//计算乘积
  t = (p-1)*(q-1);//用于与私钥e互素,同时e的值要保存
  ExtBinEuclid(&t,&e,&a,&b,&gcd);//获取公钥
  if(gcd == 1)
   d = t-b;
  //对信息进行加密
  //将字符串信息进行数据类型转化
  iMessage = atoi(szMessage.GetBuffer(szMessage.GetLength()));
  EncryValues = GetValues(iMessage,d,n);
  EncryMessage.Format(_T("%d"), EncryValues);
  return EncryMessage;
}

CString CRSA::Decrypt(CString szMessage,int e,int n)
{
  int EncryValues,iMessage;
  CString EncryMessage;
  iMessage = atoi(szMessage.GetBuffer(szMessage.GetLength()));
  EncryValues = GetValues(iMessage,e,n);
  EncryMessage.Format(_T("%d"), EncryValues);
  return EncryMessage;
}

//获取与Itemp的素数
int CRSA::GetSecretKey(int p, int q)
{
  int IResult,Itemp;
  Itemp = (p-1)*(q-1);
  for(IResult = (int)(0.2*Itemp);IResult < Itemp;IResult++)
   if(IsPrime(IResult))
    return IResult;
  return Itemp;
}

//判别是否为素数
BOOL CRSA::IsPrime(int x)
{
  int k;
  k = int(sqrt ( x ));
  for ( int i = 2; i <= k; i ++ )
  {
   if ( x % i == 0 )   
    break;
  }
  if ( i >= k + 1 )             
   return  TRUE;
  else
   return  FALSE;
}

/*
求高次模运算
输入参数:u表示公开密钥,V为n
*/
int CRSA::GetValues(int iMessage,int d,int n)
{
  int s,t,u;
  s = 1;
  t = iMessage;
  u = d;
  while(u)
  {
   if(u&1)
    s = (s*t)%n;
   u>>=1;
   t = (t*t)%n;
  }
  return s;
}

/*
求模逆元运算---欧几里德拓展算法
输入参数:u表示t,V为公开密钥
*/
void CRSA::ExtBinEuclid(int* u,int* v,int* u1,int* u2,int* u3)
{
  int k,t1,t2,t3;
  if(* u < * v)
   swap(* u,* v);
  for(k = 0;isEven(*u)&&isEven(*v);++k)
  {
   *u >>= 1;
   *v >>= 1;
  }
  *u1 = 1;
  *u2 = 0;
  *u3 = *u;
  t1 = *v;
  t2 = *u - 1;
  t3 = *v;
  do
  {
   do
   {
    if(isEven(*u3))
    {
     if(isOdd(*u1) || isOdd(*u2))
     {
      *u1 += *v;
      *u2 += *u;
     }
     *u1 >>= 1;
     *u2 >>= 1;
     *u3 >>= 1;
    }
    if(isEven(t3) || *u3 < t3)
    {
     swap(*u1,t1);
     swap(*u2,t2);
     swap(*u3,t3);
    }
   }while(isEven(*u3));
   while(*u1 < t1 || *u2 < t2)
   {
    *u1 += *v;
    *u2 += *u;
   }
   *u1 -= t1;
   *u2 -= t2;
   *u3 -= t3;
  }while(t3 > 0);
  while(*u1 >= *v && *u2 >= *u)
  {
   *u1 -= *v;
   *u2 -= *u;
  }
  *u1 <<= k;
  *u2 <<= k;
  *u3 <<= k;
}

3)、DES

// DES.h: interface for the CDES class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_DES_H__20CE37EF_1AD4_43FD_A437_9FABCF07E121__INCLUDED_)
#define AFX_DES_H__20CE37EF_1AD4_43FD_A437_9FABCF07E121__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CDES 
{
public:
  CString Decrypt();
  CString Encrypt(CString szMessage,CString szKey);
  CDES();
  virtual ~CDES();
  void Transform(int NumShift);//进行IP置换
 
private:
  int  oldMessage[64];//原来的64位明文
  int  tempByte[8];//8位字节,也就是64位
  int  Key[56];//56位密钥
  int  subKey[48];//48位子密钥, 是从56位选出来的密钥

 int  L0[32],R0[32];//对明文进行左右平分
  int  LTemp[32],RTemp[32];//临时变量
  int  KeyC0[28],KeyD0[28];//初始密钥

 int  RShift[48];//密钥移动的位数与Ki形成F函数
 
  int  S[8][6];//S盒
  int  S0[8];//初始
  int frk[32];//f函数的32位数与Ri做模2运算

 int stmp[8];//将S0存储S盒的值
  int item;
  bool isDecrypt;//是否为加密还是解密
};

#endif // !defined(AFX_DES_H__20CE37EF_1AD4_43FD_A437_9FABCF07E121__INCLUDED_)
// DES.cpp: implementation of the CDES class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "EncryAndDecrypt.h"
#include "DES.h"
#include "table.h"

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

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//默认的构造函数
CDES::CDES()
{
 
}

CDES::~CDES()
{

}

//每一轮的迭代
void CDES::Transform(int NumShift)
{
  //生成子密钥ki
  int j=2;
  // 移位次数
  if( NumShift==1||NumShift==2||NumShift==9||NumShift==16)
  {
   j=1;
  }
  //////////////////////////////////////////////////////////////////////////
  //如果为解密,迭代移位的次序变换相反方向
  if(isDecrypt)
  {
   if(NumShift == 16)
   {
    j=0;
   }
   else if(NumShift ==15||NumShift ==8||NumShift==1)
   {
    j=-1;
   }
   else
   {
    j=-2;
   }
  }
 
  int Kctmp[28], Kdtmp[28]; //  C0, D0中间传递数据
  memset(Kctmp, 0, 28);
  memset(Kdtmp, 0, 28);
  for(int i=0; i<28; i++)
  {
   Kctmp[i]=KeyC0[(i+j+28)%28];
   Kdtmp[i]=KeyD0[(i+j+28)%28];
  }
 
  //////////////////////////////////////////////////////////////////////////
  // 将KCTMP, KDTMP的数据存入KC,KD中去
  for(i=0; i<28; i++)
  {
   KeyC0[i]=Kctmp[i];
   KeyD0[i]=Kdtmp[i];
  }
 
  //////////////////////////////////////////////////////////////////////////
  // 生成子密钥Ki,存储到数组k1[48]中去
  int ktmp[56];
  memset(ktmp, 0, 56);
  for(i=0; i<28; i++)
  {
   ktmp[i]=KeyC0[i];
   ktmp[i+28]=KeyD0[i];
  }
 
  memset(subKey, 0, 48);
  for(i=0; i<48; i++)
  {
   subKey[i]=ktmp[PC2_Table[i]-1];
  }
 
  //////////////////////////////////////////////////////////////////////////
  //将Ri-1扩充成48位并与Ki相加并模2
  memset(RShift, 0, 48);
  for(i=0; i<48; i++)
  { 
   RShift[i]=(R0[E_Table[i]-1]+subKey[i])%2;
  }
 
  //////////////////////////////////////////////////////////////////////////
  //分成8组, 每组6位,有一个二维数组s[8][6]存储
  for(i=0; i<6; i++)
  {
   for(int j=0; j<8; j++)
   {
    S[j][i]=RShift[6*j+i];
   }
  }
 
  //////////////////////////////////////////////////////////////////////////
  //以下通过8个S盒得到8个S数并存到S[8]中S_Box[8][4][16]
  memset(S0, 0, 8);
  for(i=0; i<8; i++)
  {
   S0[i]=S_Box[i][S[i][5]+S[i][0]*2][S[i][1]*8+S[i][2]*4+S[i][3]*2+S[i][4]];
  }
 
  memset(stmp, 0, 8);
  memcpy(stmp, S0, sizeof(S0));
  //////////////////////////////////////////////////////////////////////////
  // 将8个数分别转换成2进制,再存入到frk[32]
  int f[32];
  memset(f, 0, 32);
  for(i=0; i<8; i++)
  {
   int tmp[4];
   memset(tmp, 0, 4);
   for(int j=0; j<4; j++)
   {
    tmp[j]=S0[i]%2;
    S0[i]/=2;
   }
   for(j=0; j<4; j++)
   {
    f[4*i+j]=tmp[3-j];
   }
  }
 
  // 经过P变换存入frk[32]
  for(i=0; i<32; i++)
  {
   frk[i]=f[P_Table[i]-1];
  }
 
  int Ltmp[32], Rtmp[32];
  memset(Ltmp, 0, 32);
  memset(Rtmp, 0, 32);
 
  for(i=0; i<32; i++)
  {
   Ltmp[i]=R0[i];
   Rtmp[i]=(L0[i]+frk[i])%2;
  }
 
  // 最后将数据存入L0,RO里面去
  for(i=0; i<32; i++)
  {
   L0[i]=Ltmp[i];
   R0[i]=Rtmp[i];
  }

}
CString CDES::Encrypt(CString szMessage,CString szKey)
{
  //初始化数组元素清0
  memset(L0, 0, 32);  
  memset(R0, 0, 32);
 
  memset(subKey, 0, 48);
  memset(KeyC0, 0, 28); 
  memset(KeyD0, 0, 28);
 
  memset(RShift, 0, 48);
  memset(oldMessage, 0, 64);
 
  memset(S, 0, 48);
  //////////////////////////////////////////////////////////////////////////
  // 此处开始加密 
  //////////////////////////////////////////////////////////////////////////
  /// 此处对明文处理,将对应的ASCII码转化为二进制 
  int flag=true;
  for(int i=0; i<8; i++)
  {
   //为szMessage输入的字符串
   char ch = szMessage.GetAt(i);
   if(ch&0x80&&flag)
   {
    AfxMessageBox("含有中文字符");
    flag=false;
   }
   memset(tempByte, 0, 8);
   for(int j=0; j<8; j++)
   {
    tempByte[j]=(ch%2+2)%2;
    ch/=2;
   }
   for(j=7; j>=0; j--)
   {
    oldMessage[i*8+7-j]=tempByte[j];
   } 
  }
 
  for(i=0; i<32; i++)
  { 
   L0[i]=oldMessage[IP_Table[i]-1];   /// 获得L0共32位
   R0[i]=oldMessage[IP_Table[i+32]-1];  /// 获得R0共32位
  }
 
  //////////////////////////////////////////////////////////////////////////
  /// 此处开始对C0,D0处理
  for(i=0; i<8; i++)
  {
   memset(tempByte, 0, 8);
   //szKey为输入的密钥
   char ch = szKey.GetAt(i);
   if(ch&0x80)
   {
    AfxMessageBox("含有中文字符");
    return "FALSESTRING";
   }
   for(int j=0; j<8; j++)
   {
    tempByte[j]=ch%2;
    ch/=2;
   }
   for(j=7; j>=0; j--)
   {
    Key[i*8+7-j]=tempByte[j];
   }
  }
 
  for(i=0; i<28; i++)
  {
   KeyC0[i]=Key[PC1_Table[i]-1];   /// 获得c0共28位
   KeyD0[i]=Key[PC1_Table[i+28]-1];  /// 获得d0共28位
  }
 
  //////////////////////////////////////////////////////////////////////////
  /// 此处开始16迭代算法
  isDecrypt=false;
  for(i=1; i<=16; i++)
  {
   Transform(i);
  }

 //////////////////////////////////////////////////////////////////////////
  // 最后一次生成的L16与R16调换位置装入密文字符串里
  int miwen[64];
  memset(miwen, 0, 64);
  // 逆初始置换,真它MOTHER的麻烦!
  int mitmp[64];
  memset(mitmp, 0, 64);
  for(i=0; i<32; i++) 
  {
   mitmp[i]=R0[i];
   mitmp[32+i]=L0[i];
   //交换L0,R0的值
   L0[i]=mitmp[i];
   R0[i]=mitmp[i+32];
  }

 for(i=0; i<64; i++) 
  {
   miwen[i]=mitmp[IPR_Table[i]-1];
  } 
  CString m_new="",str;
  for(i=0; i<8; i++)
  {
   int tmp=0;
   tmp+=miwen[8*i];
   for(int j=1; j<8; j++)
   {
    tmp*=2;
    tmp+=miwen[i*8+j];
   }
   str.Format("%c", tmp);
   m_new+=str;
  }
  return m_new;
}

//进行解密
CString CDES::Decrypt()
{
  //重新开始16次迭代算法
  isDecrypt=true;
  int i;
  for(i=16; i>=1; i--)
  {
   Transform(i);
  }
  //////////////////////////////////////////////////////////////////////////
  // 最后一次生成的L16<->R16调换位置
  int minwen[64];
  memset(minwen, 0, 64);
  // 逆初始置换
  int mintmp[64];
  memset(mintmp, 0, 64);

 for(i=0; i<32; i++) 
  {
   mintmp[i]=R0[i];
   mintmp[32+i]=L0[i];
  }
 
  for(i=0; i<64; i++) 
  {
   minwen[i]=mintmp[IPR_Table[i]-1];
  }

 //////////////////////////////////////////////////////////////////////////
  // 将密文ASCII码放入编辑框里面去
  CString str,strResult = "";
  for(i=0; i<8; i++)
  {
   int tmp=0;
   tmp+=minwen[8*i];
   for(int j=1; j<8; j++)
   {
    tmp*=2;
    tmp+=minwen[i*8+j];
   }
   //将整形变量转化为CString也可以使用itoa来解决
   str.Format("%c", tmp);
   strResult += str;
  }
  return  strResult;
}
4)、主要的窗体类:

// EncryAndDecryptDlg.h : header file
//

#if !defined(AFX_ENCRYANDDECRYPTDLG_H__DF1A4BD7_CD11_4F04_9D56_71AB1AA682C6__INCLUDED_)
#define AFX_ENCRYANDDECRYPTDLG_H__DF1A4BD7_CD11_4F04_9D56_71AB1AA682C6__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "TransparentBitmap.h"
#include "EditHex.h"
#include "EditReadOnly.h"
#include "EditSelect.h"
#include "MD5.h"
#include "DES.h"
#include "Rsa.h"

/////////////////////////////////////////////////////////////////////////////
// CEncryAndDecryptDlg dialog

class CEncryAndDecryptDlg : public CDialog
{
// Construction
public:
  CEncryAndDecryptDlg(CWnd* pParent = NULL); // standard constructor

// Dialog Data
  //{{AFX_DATA(CEncryAndDecryptDlg)
  enum { IDD = IDD_ENCRYANDDECRYPT_DIALOG };
   // NOTE: the ClassWizard will add data members here
  //}}AFX_DATA

 // ClassWizard generated virtual function overrides
  //{{AFX_VIRTUAL(CEncryAndDecryptDlg)
  public:
  virtual BOOL PreTranslateMessage(MSG* pMsg);
  protected:
  virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
  //}}AFX_VIRTUAL

// Implementation
protected:
  HICON m_hIcon;
  void ShowFileGroup(BOOL bShow);
  void ShowStringGroup(BOOL bShow);
  void MoveFileGroup();
  void MoveStringGroup();
  BOOL ToPrimeNumber(CString szTemp);
  BOOL IsPrime(int x);
  // Generated message map functions
  //{{AFX_MSG(CEncryAndDecryptDlg)
  virtual BOOL OnInitDialog();
  afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
  afx_msg void OnPaint();
  afx_msg HCURSOR OnQueryDragIcon();
  afx_msg void OnExit();
  afx_msg void OnHelp();
  afx_msg void OnRadstr();
  afx_msg void OnRadfile();
  afx_msg void OnBtnfile();
  afx_msg void OnBtnfiledigest();
  afx_msg void OnBtnsaveas();
  afx_msg void OnKickIdle();
  afx_msg void OnSelchangeCombomethods();
  afx_msg void OnRadalpha();
  afx_msg void OnRadhex();
  afx_msg void OnRaddecrypt();
  afx_msg void OnRadencrypt();
  afx_msg void OnBtnstringdigest();
  //}}AFX_MSG
  afx_msg void OnUpdateBtnFileEncry(CCmdUI* pCmdUI);
  afx_msg void OnUpdateBtnStrEncry(CCmdUI* pCmdUI);
  afx_msg void OnUpdateBtnSaveAs(CCmdUI* pCmdUI);
  afx_msg void OnUpdateEditDES(CCmdUI* pCmdUI);
  afx_msg void OnUpdateEditP(CCmdUI* pCmdUI);
  afx_msg void OnUpdateEditQ(CCmdUI* pCmdUI);
  DECLARE_MESSAGE_MAP()
private:
  int m_iRSAn;
  int m_iRSAe;
  enum {FILE = 0, STRING = 1};//对两种模式的定义
  enum {DES = 0, MD5 = 1,RSA = 2};//对使用的加密算法进行定义
  enum {ENCRYPT = 0, DECRYPT = 1};//对加密和解密进行定义
  int m_iMode;//模式变量
  int m_iMethod;//算法变量
  int m_iAction;//加密还是解密
  //颜色变量
  COLORREF m_oPlainFrg, m_oPlainBg, m_oPlainBg1;
  COLORREF m_oDigFrg, m_oDigBg, m_oDigBg1;

 CMenu m_oMenu;//菜单类,用于添加退出菜单
  CToolTipCtrl m_oToolTipCtrl;//提示信息类,主要是起到提示功能
  CTransparentBitmap m_oTransparentBitmap1,m_oTransparentBitmap2;//用于位图处理,使位图透明
  CBitmap m_oBMP1,m_oBMP2;//位图变量
  CEditSelect m_oEditDES;//IDC_EDITDES
  CEditSelect m_oEditP;//IDC_EDITP
  CEditSelect m_oEditQ;//IDC_EDITQ
  CEditSelect m_oEditFile; //IDC_EDITFILE
  CEditReadonly m_oEditStr1; //IDC_EDITSTR1
  CEditReadonly m_oEditHex1; //IDC_EDITHEX1
  CEditSelect m_oEditAlpha; //IDC_EDITALPHA
  CEditHex m_oEditHex; //IDC_EDITHEX
  CEditReadonly m_oEditStr2; //IDC_EDITSTR2
  CEditReadonly m_oEditHex2; //IDC_EDITHEX2

 //算法类
  CMD5 m_oMD5;
  CDES m_oDES; 
  CRSA m_oRSA;
};

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_ENCRYANDDECRYPTDLG_H__DF1A4BD7_CD11_4F04_9D56_71AB1AA682C6__INCLUDED_)
// EncryAndDecryptDlg.cpp : implementation file
//

#include "stdafx.h"
#include "EncryAndDecrypt.h"
#include "EncryAndDecryptDlg.h"
#include <shlwapi.h>
#include <cmath>

//动态加载库文件
#pragma comment(lib,"shlwapi.lib")

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

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
  CAboutDlg();

// Dialog Data
  //{{AFX_DATA(CAboutDlg)
  enum { IDD = IDD_ABOUTBOX };
  //}}AFX_DATA

 // ClassWizard generated virtual function overrides
  //{{AFX_VIRTUAL(CAboutDlg)
  protected:
  virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
  //}}AFX_VIRTUAL

// Implementation
protected:
  //{{AFX_MSG(CAboutDlg)
  //}}AFX_MSG
  DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
  //{{AFX_DATA_INIT(CAboutDlg)
  //}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
  CDialog::DoDataExchange(pDX);
  //{{AFX_DATA_MAP(CAboutDlg)
  //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
  //{{AFX_MSG_MAP(CAboutDlg)
   // No message handlers
  //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CEncryAndDecryptDlg dialog
//使用构造函数对控件进行初始化
CEncryAndDecryptDlg::CEncryAndDecryptDlg(CWnd* pParent /*=NULL*/)
  : CDialog(CEncryAndDecryptDlg::IDD, pParent),m_iAction(ENCRYPT),m_iMode(FILE),m_iMethod(DES),
  m_oPlainFrg(RGB(0,0,200)), m_oPlainBg(RGB(255,200,200)), m_oPlainBg1(RGB(100,200,100)),
  m_oDigFrg(RGB(0,130,0)), m_oDigBg(RGB(200,200,255)), m_oDigBg1(RGB(150,150,200)),
  m_oEditDES(RGB(20,20,100), RGB(150,200,200)),m_oEditP(RGB(20,20,100), RGB(150,200,200)),m_oEditQ(RGB(20,20,100), RGB(150,200,200)),
  m_oEditFile(m_oPlainFrg, m_oPlainBg), m_oEditStr1(m_oDigFrg, m_oDigBg),
  m_oEditHex1(m_oDigFrg, m_oDigBg),m_oEditAlpha(m_oPlainFrg, m_oPlainBg),
  m_oEditHex(m_oPlainFrg, m_oPlainBg1),m_oEditStr2(m_oDigFrg, m_oDigBg),
  m_oEditHex2(m_oDigFrg, m_oDigBg),m_iRSAe(0),m_iRSAn(0)
{
  //{{AFX_DATA_INIT(CEncryAndDecryptDlg)
   // NOTE: the ClassWizard will add member initialization here
  //}}AFX_DATA_INIT
  // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
  m_hIcon = AfxGetApp()->LoadIcon(IDR_TITLE);//显示小图标
}

void CEncryAndDecryptDlg::DoDataExchange(CDataExchange* pDX)
{
  CDialog::DoDataExchange(pDX);
  //{{AFX_DATA_MAP(CEncryAndDecryptDlg)
   // NOTE: the ClassWizard will add DDX and DDV calls here
  //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CEncryAndDecryptDlg, CDialog)
  //{{AFX_MSG_MAP(CEncryAndDecryptDlg)
  ON_WM_SYSCOMMAND()
  ON_WM_PAINT()
  ON_WM_QUERYDRAGICON()
  ON_COMMAND(IDM_EXIT, OnExit)
  ON_COMMAND(IDM_HELP, OnHelp)
  ON_BN_CLICKED(IDC_RADSTR, OnRadstr)
  ON_BN_CLICKED(IDC_RADFILE, OnRadfile)
  ON_BN_CLICKED(IDC_BTNFILE, OnBtnfile)
  ON_BN_CLICKED(IDC_BTNFILEDIGEST, OnBtnfiledigest)
  ON_BN_CLICKED(IDC_BTNSAVEAS, OnBtnsaveas)
  ON_MESSAGE_VOID(WM_KICKIDLE, OnKickIdle)
  ON_CBN_SELCHANGE(IDC_COMBO_METHODS, OnSelchangeCombomethods)
  ON_BN_CLICKED(IDC_RADALPHA, OnRadalpha)
  ON_BN_CLICKED(IDC_RADHEX, OnRadhex)
  ON_BN_CLICKED(IDC_RADDECRYPT, OnRaddecrypt)
  ON_BN_CLICKED(IDC_RADENCRYPT, OnRadencrypt)
  ON_UPDATE_COMMAND_UI(IDC_BTNFILEDIGEST, OnUpdateBtnFileEncry)
  ON_UPDATE_COMMAND_UI(IDC_BTNSTRINGDIGEST, OnUpdateBtnStrEncry)
  ON_UPDATE_COMMAND_UI(IDC_BTNSAVEAS, OnUpdateBtnSaveAs)
  ON_UPDATE_COMMAND_UI(IDC_EDITDES, OnUpdateEditDES)
  ON_UPDATE_COMMAND_UI(IDC_EDITP, OnUpdateEditP)
  ON_UPDATE_COMMAND_UI(IDC_EDITQ, OnUpdateEditQ)
  ON_BN_CLICKED(IDC_BTNSTRINGDIGEST, OnBtnstringdigest)
  //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CEncryAndDecryptDlg message handlers


//下面是16进制和字符以及二进制相互转化的全局函数
//将字符转化为16进制
void Char2Hex(unsigned char ch, char* szHex)
{
  static unsigned char saucHex[] = "0123456789ABCDEF";
  szHex[0] = saucHex[ch >> 4];
  szHex[1] = saucHex[ch&0xF];
  szHex[2] = 0;
}

//将16进制数据转化为字符类型
bool Hex2Char(char const* szHex, unsigned char& rch)
{
  if(*szHex >= '0' && *szHex <= '9')
   rch = *szHex - '0';
  else if(*szHex >= 'A' && *szHex <= 'F')
   rch = *szHex - 55;
  else
   //不是16进制数据
   return false;
  szHex++;
  if(*szHex >= '0' && *szHex <= '9')
   (rch <<= 4) += *szHex - '0';
  else if(*szHex >= 'A' && *szHex <= 'F')
   (rch <<= 4) += *szHex - 55;
  else
   //不是16进制数据
   return false;
  return true;
}

//将二进制数据转化为16进制数据
void Binary2Hex(unsigned char const* pucBinStr, int iBinSize, char* pszHexStr)
{
  int i;
  char szHex[3];
  unsigned char const* pucBinStr1 = pucBinStr;
  *pszHexStr = 0;
  for(i=0; i<iBinSize; i++,pucBinStr1++)
  {
   Char2Hex(*pucBinStr1, szHex);
   strcat(pszHexStr, szHex);
  }
}

//将16进制转化为2进制
bool Hex2Binary(char const* pszHexStr, unsigned char* pucBinStr, int iBinSize)
{
  int i;
  unsigned char ch;
  for(i=0; i<iBinSize; i++,pszHexStr+=2,pucBinStr++)
  {
   if(false == Hex2Char(pszHexStr, ch))
    return false;
   *pucBinStr = ch;
  }
  return true;
}

BOOL CEncryAndDecryptDlg::OnInitDialog()
{
  CDialog::OnInitDialog();

 // Add "About..." menu item to system menu.

 // IDM_ABOUTBOX must be in the system command range.
  ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
  ASSERT(IDM_ABOUTBOX < 0xF000);

 CMenu* pSysMenu = GetSystemMenu(FALSE);
  if (pSysMenu != NULL)
  {
   CString strAboutMenu;
   strAboutMenu.LoadString(IDS_ABOUTBOX);
   if (!strAboutMenu.IsEmpty())
   {
    pSysMenu->AppendMenu(MF_SEPARATOR);
    pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
   }
  }

 // Set the icon for this dialog.  The framework does this automatically
  //  when the application's main window is not a dialog
  SetIcon(m_hIcon, TRUE);   // Set big icon
  SetIcon(m_hIcon, FALSE);  // Set small icon
 
  // TODO: Add extra initialization here
  //添加自己的菜单资源
  m_oMenu.LoadMenu(IDR_MENU);
  SetMenu(&m_oMenu);

 //对控件颜色进行显示
  m_oEditDES.SubclassDlgItem(IDC_EDITDES,this);
  m_oEditP.SubclassDlgItem(IDC_EDITP,this);
  m_oEditQ.SubclassDlgItem(IDC_EDITQ,this);
  m_oEditFile.SubclassDlgItem(IDC_EDITFILE, this);
  m_oEditStr1.SubclassDlgItem(IDC_EDITSTR1, this);
  m_oEditHex1.SubclassDlgItem(IDC_EDITHEX1, this);
  m_oEditAlpha.SubclassDlgItem(IDC_EDITALPHA, this);
  m_oEditHex.SubclassDlgItem(IDC_EDITHEX, this);
  m_oEditStr2.SubclassDlgItem(IDC_EDITSTR2, this);
  m_oEditHex2.SubclassDlgItem(IDC_EDITHEX2, this);

 //对控件进行提示,便于用户进行输入
  if(!m_oToolTipCtrl.Create(this))
  {
   TRACE("\nUnable to create ToolTip control");//创建失败
  }
  else
  {
   //添加提示信息
   m_oToolTipCtrl.AddTool(&m_oEditDES,IDS_EDITDES);
   m_oToolTipCtrl.AddTool(&m_oEditP,IDS_EDITP);
   m_oToolTipCtrl.AddTool(&m_oEditQ,IDS_EDITQ);
   m_oToolTipCtrl.AddTool(&m_oEditFile,IDS_EDITFILE);
   m_oToolTipCtrl.AddTool(&m_oEditStr1,IDS_EDITSTR1);
   m_oToolTipCtrl.AddTool(&m_oEditHex1,IDS_EDITHEX1);
   m_oToolTipCtrl.AddTool(&m_oEditAlpha,IDS_EDITALPHA);
   m_oToolTipCtrl.AddTool(&m_oEditHex,IDS_EDITHEX);
   m_oToolTipCtrl.AddTool(&m_oEditStr2,IDS_EDITSTR2);
   m_oToolTipCtrl.AddTool(&m_oEditHex2,IDS_EDITHEX2);
   //激活控件
   m_oToolTipCtrl.Activate(TRUE);
  }
  //初始化显示文件面板
  CRect oRect, oRectDlg;
  CWnd* poWnd = GetDlgItem(IDC_EDITHEX1);
  poWnd->GetWindowRect(&oRect);
  GetWindowRect(&oRectDlg);
  SetWindowPos(NULL, 0, 0, oRectDlg.Width(), oRect.bottom-oRectDlg.top+15, SWP_NOMOVE|SWP_NOZORDER);//通过设置窗体位置来确定文件面板
  //初始化单选框
  CButton* poButton;
  poButton = (CButton*)(GetDlgItem(IDC_RADFILE));//或者使用poButton = reinterpret_cast<CButton*>(GetDlgItem(IDC_RADFILE));
  poButton->SetCheck(1);
  poButton = (CButton*)(GetDlgItem(IDC_RADALPHA));//或者使用poButton = reinterpret_cast<CButton*>(GetDlgItem(IDC_RADALPHA));
  poButton->SetCheck(1);
  poButton = (CButton*)(GetDlgItem(IDC_RADENCRYPT));//或者使用poButton = reinterpret_cast<CButton*>(GetDlgItem(IDC_RADENCRYPT));
  poButton->SetCheck(1);
  //初始化组合框
  CComboBox* poComboBox;
  poComboBox = (CComboBox*)(GetDlgItem(IDC_COMBO_METHODS));//或者使用poComboBox = static_cast<CComboBox*>(GetDlgItem(IDC_COMBO_METHODS));
  poComboBox->SetCurSel(0);

 //显示位图资源
  m_oBMP1.LoadBitmap(IDB_BMPDOWN);
  m_oBMP2.LoadBitmap(IDB_BMPUP);
  //对文件面板的位图进行显示
  m_oTransparentBitmap1.SubclassDlgItem(IDC_STATICBMPARROW1, this);
  m_oTransparentBitmap1.Initialize(HBITMAP(m_oBMP1), RGB(255,255,255), 1.0, 1.0);
  //对字符串面板的位图进行显示
  m_oTransparentBitmap2.SubclassDlgItem(IDC_STATICBMPARROW2, this);
  m_oTransparentBitmap2.Initialize(HBITMAP(m_oBMP1), RGB(255,255,255), 1.0, 1.0);

 return TRUE;  // return TRUE  unless you set the focus to a control
}

//通过处理鼠标事件来添加提示控件处理信息
BOOL CEncryAndDecryptDlg::PreTranslateMessage(MSG* pMsg)
{
  // TODO: Add your specialized code here and/or call the base class
  //通过鼠标来显示提示信息
  m_oToolTipCtrl.RelayEvent(pMsg);
  return CDialog::PreTranslateMessage(pMsg);
}

void CEncryAndDecryptDlg::OnKickIdle()
{
    //Call this member function to update the state of dialog buttons and other controls
    //in a dialog box or window that uses the ON_UPDATE_COMMAND_UI callback mechanism
  UpdateDialogControls( this, FALSE );
}

void CEncryAndDecryptDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
  if ((nID & 0xFFF0) == IDM_ABOUTBOX)
  {
   CAboutDlg dlgAbout;
   dlgAbout.DoModal();
  }
  else
  {
   CDialog::OnSysCommand(nID, lParam);
  }
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CEncryAndDecryptDlg::OnPaint()
{
  if (IsIconic())
  {
   CPaintDC dc(this); // device context for painting

  SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

  // Center icon in client rectangle
   int cxIcon = GetSystemMetrics(SM_CXICON);
   int cyIcon = GetSystemMetrics(SM_CYICON);
   CRect rect;
   GetClientRect(&rect);
   int x = (rect.Width() - cxIcon + 1) / 2;
   int y = (rect.Height() - cyIcon + 1) / 2;

  // Draw the icon
   dc.DrawIcon(x, y, m_hIcon);
  }
  else
  {
   CDialog::OnPaint();
  }
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CEncryAndDecryptDlg::OnQueryDragIcon()
{
  return (HCURSOR) m_hIcon;
}

//处理退出菜单事件
void CEncryAndDecryptDlg::OnExit()
{
  CDialog::EndDialog(IDOK);
}

void CEncryAndDecryptDlg::OnHelp()
{
  CAboutDlg dlg;
  dlg.DoModal();
}
//显示File模式面板
void CEncryAndDecryptDlg::OnRadfile()
{
  //将字符串面板屏蔽
  ShowStringGroup(FALSE);
  MoveFileGroup();
  //将文件面板所有控件显示
  ShowFileGroup(TRUE);
  //重新设置面板显示的位置
  CRect oRect, oRectDlg;
  CWnd* poWnd = GetDlgItem(IDC_EDITHEX1);
  poWnd->GetWindowRect(&oRect);
  GetWindowRect(&oRectDlg);
  SetWindowPos(NULL, 0, 0, oRectDlg.Width(), oRect.bottom-oRectDlg.top+15, SWP_NOMOVE|SWP_NOZORDER);
  m_iMode = FILE;
}

//显示String模式面板
void CEncryAndDecryptDlg::OnRadstr()
{
  //将文件面板屏蔽
  ShowFileGroup(FALSE);
  MoveStringGroup();
  //将字符串面板所有控件显示
  ShowStringGroup(TRUE);
  //重新设置字符串面板显示的位置
  CRect oRect, oRectDlg;
  CWnd* poWnd = GetDlgItem(IDC_EDITHEX2);
  poWnd->GetWindowRect(&oRect);
  GetWindowRect(&oRectDlg);
  SetWindowPos(NULL, 0, 0, oRectDlg.Width(), oRect.bottom-oRectDlg.top+15, SWP_NOMOVE|SWP_NOZORDER);
  m_iMode = STRING;
}
//显示File模式所对应的面板上的所有控件
void CEncryAndDecryptDlg::ShowFileGroup(BOOL bShow)
{
  CWnd* poWnd;
  //显示各个控件
  poWnd = GetDlgItem(IDC_LBLFILE);
  poWnd->ShowWindow(bShow ? SW_SHOW : SW_HIDE);
  poWnd = GetDlgItem(IDC_EDITFILE);
  poWnd->ShowWindow(bShow ? SW_SHOW : SW_HIDE);
  poWnd = GetDlgItem(IDC_BTNFILE);
  poWnd->ShowWindow(bShow ? SW_SHOW : SW_HIDE);
  poWnd = GetDlgItem(IDC_STATICBMPARROW1);
  poWnd->ShowWindow(bShow ? SW_SHOW : SW_HIDE);
  poWnd = GetDlgItem(IDC_BTNFILEDIGEST);
  poWnd->ShowWindow(bShow ? SW_SHOW : SW_HIDE);
  poWnd = GetDlgItem(IDC_LBLSTR1);
  poWnd->ShowWindow(bShow ? SW_SHOW : SW_HIDE);
  poWnd = GetDlgItem(IDC_EDITSTR1);
  poWnd->ShowWindow(bShow ? SW_SHOW : SW_HIDE);
  poWnd = GetDlgItem(IDC_BTNSAVEAS);
  poWnd->ShowWindow(bShow ? SW_SHOW : SW_HIDE);
  poWnd = GetDlgItem(IDC_LBLHEX1);
  poWnd->ShowWindow(bShow ? SW_SHOW : SW_HIDE);
  poWnd = GetDlgItem(IDC_EDITHEX1);
  poWnd->ShowWindow(bShow ? SW_SHOW : SW_HIDE);
}

//显示String模式所对应的面板上的所有控件
void CEncryAndDecryptDlg::ShowStringGroup(BOOL bShow)
{
  CWnd* poWnd;
  //显示各个控件
  poWnd = GetDlgItem(IDC_LBLSTR);
  poWnd->ShowWindow(bShow ? SW_SHOW : SW_HIDE);
  poWnd = GetDlgItem(IDC_EDITALPHA);
  poWnd->ShowWindow(bShow ? SW_SHOW : SW_HIDE);
  poWnd = GetDlgItem(IDC_EDITHEX);
  poWnd->ShowWindow(bShow ? SW_SHOW : SW_HIDE);
  poWnd = GetDlgItem(IDC_RADALPHA);
  poWnd->ShowWindow(bShow ? SW_SHOW : SW_HIDE);
  poWnd = GetDlgItem(IDC_RADHEX);
  poWnd->ShowWindow(bShow ? SW_SHOW : SW_HIDE);
  poWnd = GetDlgItem(IDC_STATICBMPARROW2);
  poWnd->ShowWindow(bShow ? SW_SHOW : SW_HIDE);
  poWnd = GetDlgItem(IDC_BTNSTRINGDIGEST);
  poWnd->ShowWindow(bShow ? SW_SHOW : SW_HIDE);
  poWnd = GetDlgItem(IDC_LBLSTR2);
  poWnd->ShowWindow(bShow ? SW_SHOW : SW_HIDE);
  poWnd = GetDlgItem(IDC_EDITSTR2);
  poWnd->ShowWindow(bShow ? SW_SHOW : SW_HIDE);
  poWnd = GetDlgItem(IDC_LBLHEX2);
  poWnd->ShowWindow(bShow ? SW_SHOW : SW_HIDE);
  poWnd = GetDlgItem(IDC_EDITHEX2);
  poWnd->ShowWindow(bShow ? SW_SHOW : SW_HIDE);
}
void CEncryAndDecryptDlg::MoveFileGroup()
{
  //获取y坐标
  CRect oRect;
  CWnd* poWnd;
  poWnd = GetDlgItem(IDC_BORDER);
  poWnd->GetWindowRect(&oRect);
  int iYRef = oRect.bottom;
  poWnd = GetDlgItem(IDC_LBLFILE);
  poWnd->GetWindowRect(&oRect);
  int iDelta = oRect.top - iYRef;
  //坐标转化
  ScreenToClient(oRect);
  poWnd->SetWindowPos(NULL, oRect.left, oRect.top-iDelta, 0, 0, SWP_NOSIZE|SWP_NOZORDER);
  //设置各个控件的位置
  //
  poWnd = GetDlgItem(IDC_EDITFILE);
  poWnd->GetWindowRect(&oRect);
  ScreenToClient(oRect);
  poWnd->SetWindowPos(NULL, oRect.left, oRect.top-iDelta, 0, 0, SWP_NOSIZE|SWP_NOZORDER);
  //
  poWnd = GetDlgItem(IDC_BTNFILE);
  poWnd->GetWindowRect(&oRect);
  ScreenToClient(oRect);
  poWnd->SetWindowPos(NULL, oRect.left, oRect.top-iDelta, 0, 0, SWP_NOSIZE|SWP_NOZORDER);
  //
  poWnd = GetDlgItem(IDC_STATICBMPARROW1);
  poWnd->GetWindowRect(&oRect);
  ScreenToClient(oRect);
  poWnd->SetWindowPos(NULL, oRect.left, oRect.top-iDelta, 0, 0, SWP_NOSIZE|SWP_NOZORDER);
  //
  poWnd = GetDlgItem(IDC_BTNFILEDIGEST);
  poWnd->GetWindowRect(&oRect);
  ScreenToClient(oRect);
  poWnd->SetWindowPos(NULL, oRect.left, oRect.top-iDelta, 0, 0, SWP_NOSIZE|SWP_NOZORDER);
  //
  poWnd = GetDlgItem(IDC_LBLSTR1);
  poWnd->GetWindowRect(&oRect);
  ScreenToClient(oRect);
  poWnd->SetWindowPos(NULL, oRect.left, oRect.top-iDelta, 0, 0, SWP_NOSIZE|SWP_NOZORDER);
  //
  poWnd = GetDlgItem(IDC_EDITSTR1);
  poWnd->GetWindowRect(&oRect);
  ScreenToClient(oRect);
  poWnd->SetWindowPos(NULL, oRect.left, oRect.top-iDelta, 0, 0, SWP_NOSIZE|SWP_NOZORDER);
  //
  poWnd = GetDlgItem(IDC_BTNSAVEAS);
  poWnd->GetWindowRect(&oRect);
  ScreenToClient(oRect);
  poWnd->SetWindowPos(NULL, oRect.left, oRect.top-iDelta, 0, 0, SWP_NOSIZE|SWP_NOZORDER);
  //
  poWnd = GetDlgItem(IDC_LBLHEX1);
  poWnd->GetWindowRect(&oRect);
  ScreenToClient(oRect);
  poWnd->SetWindowPos(NULL, oRect.left, oRect.top-iDelta, 0, 0, SWP_NOSIZE|SWP_NOZORDER);
  //
  poWnd = GetDlgItem(IDC_EDITHEX1);
  poWnd->GetWindowRect(&oRect);
  ScreenToClient(oRect);
  poWnd->SetWindowPos(NULL, oRect.left, oRect.top-iDelta, 0, 0, SWP_NOSIZE|SWP_NOZORDER);
}
void CEncryAndDecryptDlg::MoveStringGroup()
{
  //获取y坐标
  CRect oRect;
  CWnd* poWnd;
  poWnd = GetDlgItem(IDC_BORDER);
  poWnd->GetWindowRect(&oRect);
  int iYRef = oRect.bottom;
  poWnd = GetDlgItem(IDC_LBLSTR);
  poWnd->GetWindowRect(&oRect);
  int iDelta = oRect.top - iYRef;
  //坐标转化
  ScreenToClient(oRect);
  poWnd->SetWindowPos(NULL, oRect.left, oRect.top-iDelta, 0, 0, SWP_NOSIZE|SWP_NOZORDER);
  //设置各个控件的位置
  //
  poWnd = GetDlgItem(IDC_EDITALPHA);
  poWnd->GetWindowRect(&oRect);
  ScreenToClient(oRect);
  poWnd->SetWindowPos(NULL, oRect.left, oRect.top-iDelta, 0, 0, SWP_NOSIZE|SWP_NOZORDER);
  //
  poWnd = GetDlgItem(IDC_EDITHEX);
  poWnd->GetWindowRect(&oRect);
  ScreenToClient(oRect);
  poWnd->SetWindowPos(NULL, oRect.left, oRect.top-iDelta, 0, 0, SWP_NOSIZE|SWP_NOZORDER);
  //
  poWnd = GetDlgItem(IDC_RADALPHA);
  poWnd->GetWindowRect(&oRect);
  ScreenToClient(oRect);
  poWnd->SetWindowPos(NULL, oRect.left, oRect.top-iDelta, 0, 0, SWP_NOSIZE|SWP_NOZORDER);
  //
  poWnd = GetDlgItem(IDC_RADHEX);
  poWnd->GetWindowRect(&oRect);
  ScreenToClient(oRect);
  poWnd->SetWindowPos(NULL, oRect.left, oRect.top-iDelta, 0, 0, SWP_NOSIZE|SWP_NOZORDER);
  //
  poWnd = GetDlgItem(IDC_STATICBMPARROW2);
  poWnd->GetWindowRect(&oRect);
  ScreenToClient(oRect);
  poWnd->SetWindowPos(NULL, oRect.left, oRect.top-iDelta, 0, 0, SWP_NOSIZE|SWP_NOZORDER);
  //
  poWnd = GetDlgItem(IDC_BTNSTRINGDIGEST);
  poWnd->GetWindowRect(&oRect);
  ScreenToClient(oRect);
  poWnd->SetWindowPos(NULL, oRect.left, oRect.top-iDelta, 0, 0, SWP_NOSIZE|SWP_NOZORDER);
  //
  poWnd = GetDlgItem(IDC_LBLSTR2);
  poWnd->GetWindowRect(&oRect);
  ScreenToClient(oRect);
  poWnd->SetWindowPos(NULL, oRect.left, oRect.top-iDelta, 0, 0, SWP_NOSIZE|SWP_NOZORDER);
  //
  poWnd = GetDlgItem(IDC_EDITSTR2);
  poWnd->GetWindowRect(&oRect);
  ScreenToClient(oRect);
  poWnd->SetWindowPos(NULL, oRect.left, oRect.top-iDelta, 0, 0, SWP_NOSIZE|SWP_NOZORDER);
  //
  poWnd = GetDlgItem(IDC_LBLHEX2);
  poWnd->GetWindowRect(&oRect);
  ScreenToClient(oRect);
  poWnd->SetWindowPos(NULL, oRect.left, oRect.top-iDelta, 0, 0, SWP_NOSIZE|SWP_NOZORDER);
  //
  poWnd = GetDlgItem(IDC_EDITHEX2);
  poWnd->GetWindowRect(&oRect);
  ScreenToClient(oRect);
  poWnd->SetWindowPos(NULL, oRect.left, oRect.top-iDelta, 0, 0, SWP_NOSIZE|SWP_NOZORDER);
}

//点击浏览按钮
void CEncryAndDecryptDlg::OnBtnfile()
{
  // TODO: Add your control notification handler code here
  CFileDialog m_FileOpen(TRUE);
  //设置打开窗体的标题
    m_FileOpen.m_ofn.lpstrTitle = _T("打开文件");
    m_FileOpen.m_ofn.lpstrFilter = _T("文件 (*.*)\0*.*\0\0");
  //点击浏览按钮
  if(IDOK == m_FileOpen.DoModal())
  {
   //获取打开的文件路径
   CString m_FileName = m_FileOpen.GetPathName();
   CEdit* pEdit = (CEdit*)(GetDlgItem(IDC_EDITFILE));
   //将选择的文件路径名显示到IDC_EDITFILE表识的EDIT中
   pEdit->SetWindowText(m_FileName);
  }
}

//点击按钮保存
void CEncryAndDecryptDlg::OnBtnsaveas()
{
  // TODO: Add your control notification handler code here
  CFileDialog oFileOpen(FALSE);
  //设置保存文件的标题
    oFileOpen.m_ofn.lpstrTitle = _T("保存加密文件");
    oFileOpen.m_ofn.lpstrFilter = _T("文件格式 (*.txt)\0*.txt\0(*.*)\0*.*\0\0");
  if(oFileOpen.DoModal() == IDOK)
  {
   //获取文件路径
   CString oStrFileName = oFileOpen.GetPathName();
   oStrFileName += ".txt";
   CFile oFile;
   //文件异常类,用于捕获文件异常
   CFileException oFileException;
   TCHAR szBuff[MAX_PATH+1];
   _tcscpy(szBuff, LPCTSTR(oStrFileName));
   //获取路径或文件名中的文件扩展名
   CString pcExt = ::PathFindExtension(oStrFileName);
   //创建文件来保存,以二进制形式来保存
   BOOL bOpen = oFile.Open(oStrFileName, CFile::modeCreate|CFile::modeWrite|CFile::typeBinary, &oFileException);
   if(bOpen == TRUE)
   {
    //打开文件处理
    char acDigest[65] = {0};
    CEdit* poEdit = (CEdit*)(GetDlgItem(IDC_EDITHEX1));
    CString oStrHex;
    poEdit->GetWindowText(oStrHex);
    int iLength;
    switch(m_iMethod)
    {
     case DES:
      AfxMessageBox("采用DES算法");
      break;
     case MD5:
      iLength = 16;
      break;
     case RSA:
      AfxMessageBox("采用RSA算法");
      break;
     default:
      ASSERT(0);
    }
    Hex2Binary(LPCTSTR(oStrHex), reinterpret_cast<unsigned char*>(acDigest), iLength);
    oFile.Write(acDigest, iLength);
    oFile.Close();
    AfxMessageBox("保存文件成功!");
   }
   else
   {
    AfxMessageBox("保存文件失败!");
   }
  }
}

//使文件加密按钮有效
void CEncryAndDecryptDlg::OnUpdateBtnFileEncry(CCmdUI* pCmdUI)
{
  BOOL m_bTemp = TRUE;
  CEdit* pEdit = (CEdit*)(GetDlgItem(IDC_EDITFILE));
  //当没有输入IDC_EDITFILE的字符长度或者算法选择MD5同时为解密算法,按钮无效
  if(pEdit->GetWindowTextLength() <= 0)
   m_bTemp = FALSE;
  if((m_iMethod == MD5) && (m_iAction == DECRYPT))
   m_bTemp = FALSE;
  pCmdUI->Enable(m_bTemp);
}

//使文件加密按钮有效
void CEncryAndDecryptDlg::OnUpdateBtnStrEncry(CCmdUI* pCmdUI)
{
  BOOL m_bTemp = TRUE;
  CEdit* pEdit1,*pEdit2;
  pEdit1 = (CEdit*)(GetDlgItem(IDC_EDITSTR2));
  pEdit2 = (CEdit*)(GetDlgItem(IDC_EDITALPHA));
  if(m_iAction == ENCRYPT)//加密时的处理
  {
   //当算法选择MD5同时为解密算法,按钮无效
   if((m_iMethod == MD5) && (m_iAction == DECRYPT))
    m_bTemp = FALSE;
   pCmdUI->Enable(m_bTemp);
  }
  else//解密时的处理
  {
   //当IDC_EDITSTR2没有信息时候
   if(pEdit1->GetWindowTextLength() <= 0)
    m_bTemp = FALSE;
   //用于设置解密只能一次
   if(pEdit2->GetWindowTextLength() && m_iMethod == DES)
    m_bTemp = FALSE;
   if((m_iMethod == MD5) && (m_iAction == DECRYPT))
    m_bTemp = FALSE;
   if((m_iMethod == RSA) && (pEdit2->GetWindowTextLength() > 0))
    m_bTemp = FALSE;
   pCmdUI->Enable(m_bTemp);
  }
}

//使保存按钮有效
void CEncryAndDecryptDlg::OnUpdateBtnSaveAs(CCmdUI* pCmdUI)
{
  CEdit* pEdit = (CEdit*)(GetDlgItem(IDC_EDITSTR1));
  //当有字符串输入到ID号为IDC_EDITSTR1的EDITBOX里面,该按钮就有效
  pCmdUI->Enable(pEdit->GetWindowTextLength() > 0);
}

//使ID号为IDC_EDITDES的EDITBOX变得有效或者无效
void CEncryAndDecryptDlg::OnUpdateEditDES(CCmdUI* pCmdUI)
{
/* BOOL m_bTemp = TRUE;
  if((m_iMethod == MD5) || (m_iMethod == RSA))
   m_bTemp = FALSE;*/
  pCmdUI->Enable(m_iMethod == DES);
}

//使ID号为IDC_EDITP的EDITBOX变得有效或者无效
void CEncryAndDecryptDlg::OnUpdateEditP(CCmdUI* pCmdUI)
{
  pCmdUI->Enable(m_iMethod == RSA);
}

//使ID号为IDC_EDITQ的EDITBOX变得有效或者无效
void CEncryAndDecryptDlg::OnUpdateEditQ(CCmdUI* pCmdUI)
{
  pCmdUI->Enable(m_iMethod == RSA);
}

//判别使用什么加密算法
void CEncryAndDecryptDlg::OnSelchangeCombomethods()
{
  CComboBox* poComboBox;
  poComboBox = (CComboBox*)(GetDlgItem(IDC_COMBO_METHODS));
  int iSel = poComboBox->GetCurSel();
  ASSERT((iSel >= DES)&&(iSel <= RSA));
  m_iMethod = iSel;//获取选中的值
}

//点击单选框字符时的处理
void CEncryAndDecryptDlg::OnRadalpha()
{
  // TODO: Add your control notification handler code here
  //使字符串EDITBOX有效
  m_oEditAlpha.EnableWindow(TRUE);
  //对该EDITBOX重新设置背景
  m_oEditAlpha.SetBkColor(m_oPlainBg);
  //使16进制EDITBOX无效
  m_oEditHex.EnableWindow(FALSE);
  //对该EDITBOX重新设置背景
  m_oEditHex.SetBkColor(m_oPlainBg1);
}

//点击单选框16进制时的处理
void CEncryAndDecryptDlg::OnRadhex()
{
  // TODO: Add your control notification handler code here
  //使字符串EDITBOX无效
  m_oEditAlpha.EnableWindow(FALSE);
  //对该EDITBOX重新设置背景
  m_oEditAlpha.SetBkColor(m_oPlainBg1);
  //使16进制EDITBOX有效
  m_oEditHex.EnableWindow(TRUE);
  //对该EDITBOX重新设置背景
  m_oEditHex.SetBkColor(m_oPlainBg);
}

//点击单选框解密时的处理
void CEncryAndDecryptDlg::OnRaddecrypt()
{
  // TODO: Add your control notification handler code here
  //记录动作为解密
  m_iAction = DECRYPT;
  //改变按钮为解密
  CButton* poButton1 = (CButton*)(GetDlgItem(IDC_BTNFILEDIGEST));
  poButton1->SetWindowText("&文件解密");
  CButton *poButton2 = (CButton*)(GetDlgItem(IDC_BTNSTRINGDIGEST));
  poButton2->SetWindowText("&字符串解密");
  //更换位图
  m_oTransparentBitmap1.ChangeBitmap(HBITMAP(m_oBMP2));
  m_oTransparentBitmap2.ChangeBitmap(HBITMAP(m_oBMP2));
}

//点击单选框加密时的处理
void CEncryAndDecryptDlg::OnRadencrypt()
{
  // TODO: Add your control notification handler code here
  //记录动作为加密
  m_iAction = ENCRYPT;
  //改变按钮为加密
  CButton* poButton1 = (CButton*)(GetDlgItem(IDC_BTNFILEDIGEST));
  poButton1->SetWindowText("&文件加密");
  CButton *poButton2 = (CButton*)(GetDlgItem(IDC_BTNSTRINGDIGEST));
  poButton2->SetWindowText("&字符串加密");
  //更换位图
  m_oTransparentBitmap1.ChangeBitmap(HBITMAP(m_oBMP1));
  m_oTransparentBitmap2.ChangeBitmap(HBITMAP(m_oBMP1));
}

//对文件进行加密处理
void CEncryAndDecryptDlg::OnBtnfiledigest()
{
  // TODO: Add your control notification handler code here、
  //判别算法为加密算法还是解密算法
  CButton* poAction = (CButton*)(GetDlgItem(IDC_RADENCRYPT));
  //从EDIT中获取文件名
  CString strFileName;
  CEdit* poEdit = (CEdit*)(GetDlgItem(IDC_EDITFILE));
  poEdit->GetWindowText(strFileName);
  //确定选择的方法
  /*switch(m_iMethod)
  {
   case DES:
    AfxMessageBox("采用DES算法");
    break;
   case MD5:
    AfxMessageBox("采用MD5算法");
    break;
   case RSA:
    AfxMessageBox("采用RSA算法");
    break;
  }*/
  //对文件进行加密解密
  char acDigest[65] = {0};
  char szHexDigest[129] = {0};
  int iLength;
  //判别为加密算法还是解密算法
  if(poAction->GetCheck() == 1)//为加密算法
  {
   m_iAction = ENCRYPT;
   switch(m_iMethod)
   {
    case DES:
     AfxMessageBox("采用DES算法加密显示结果");
     break;
    case MD5:
     AfxMessageBox("采用MD5算法加密显示结果");
     //对摘要进行加密
     m_oMD5.DigestFile(LPCTSTR(strFileName), acDigest);
     Binary2Hex(reinterpret_cast<unsigned char*>(acDigest), 16, szHexDigest);
     iLength = 16;
     break;
    case RSA:
     AfxMessageBox("采用RSA算法加密显示结果");
     break;
   }
   //将结果显示出来
   poEdit = (CEdit*)(GetDlgItem(IDC_EDITHEX1));
   poEdit->SetWindowText(szHexDigest);
   //判别是否存在非法字符
   for(int i=0; i<iLength; i++)
    if(acDigest[i] == 0)
     acDigest[i] = 0x0A; 
   poEdit = (CEdit*)(GetDlgItem(IDC_EDITSTR1));
   poEdit->SetWindowText(acDigest);
  }
  else//解密算法
  {
   m_iAction = DECRYPT;
   switch(m_iMethod)
   {
    case DES:
     AfxMessageBox("DES算法解密显示结果");
     break;
    case MD5://解密按钮已经被屏蔽掉
     break;
    case RSA:
     AfxMessageBox("采用RSA算法解密显示结果");
     break;
   } 
  }
}

//对字符串或者是16进制数据进行加密或者解密
void CEncryAndDecryptDlg::OnBtnstringdigest()
{
  // TODO: Add your control notification handler code here
  //判别算法为加密算法还是解密算法
  CButton* poAction = (CButton*)(GetDlgItem(IDC_RADENCRYPT));
  CEdit* poEdit;
  //获取单选框的值,用于区分为字符串还是16进制数据
  CButton* poButton = (CButton*)(GetDlgItem(IDC_RADALPHA));
  //确定选择的方法
  /*switch(m_iMethod)
  {
   case DES:
    AfxMessageBox("采用DES算法");
    break;
   case MD5:
    AfxMessageBox("采用MD5算法");
    break;
   case RSA:
    AfxMessageBox("采用RSA算法");
    break;
  }*/
  CString strTemp,strPrimeP,strPrimeQ;//用于获取EDIT中输入的信息
  char acDigest[65] = {0};
  int  iLen;
  //判别为加密算法还是解密算法
  if(poAction->GetCheck() == 1)//为加密算法
  {
   m_iAction = ENCRYPT;
   //判别为字符串还是为16进制形式
   if(poButton->GetCheck() == 1)//为字符串形式
   {
    poEdit = (CEdit*)(GetDlgItem(IDC_EDITALPHA));
    poEdit->GetWindowText(strTemp);
    if(m_iMethod == DES && strTemp.GetLength() != 8)
    {
     AfxMessageBox("输入的加密的字符串长度不是8位,请重试!");
     return;
    }
    m_oMD5.Reset();
    m_oMD5.AddData(LPCTSTR(strTemp),strTemp.GetLength());
    m_oMD5.FinalDigest(acDigest);
   }
   else//为16进制形式
   {
    poEdit = (CEdit*)(GetDlgItem(IDC_EDITHEX));
    poEdit->GetWindowText(strTemp);
    iLen = strTemp.GetLength()/2;
    char* pcData = static_cast<char*>(_alloca(iLen));
    Hex2Binary(LPCTSTR(strTemp), reinterpret_cast<unsigned char*>(pcData), iLen);
    m_oMD5.Reset();
    m_oMD5.AddData(pcData, iLen);
    m_oMD5.FinalDigest(acDigest);
   }
   //下面就是实现将输出的结果显示在EDIT里面就可以了
   char acHex[129] = {0};
   poEdit = (CEdit*)(GetDlgItem(IDC_EDITHEX2));
   CString strKey,strResult;
   CStatic* poStatic;
   int iLength,i,iPrimeP = 0,iPrimeQ = 0,iSubkey = 0;
   switch(m_iMethod)
   {
    case DES:
     CEdit* poEditKey;
     poEditKey = (CEdit*)GetDlgItem(IDC_EDITDES);
     poEditKey->GetWindowText(strKey);
     //判断密钥的长度是否为8位
     if(strKey.GetLength() != 8)
     {
      AfxMessageBox("输入的密钥长度不是8位,请重试!");
      return;
     }
     //判别里面时候存在中文字符
     for(i = 0;i< 8;i++)
     {
      //重字符串中获取第i个字符
      char ch = strKey.GetAt(i);
      //判别是否存在非法字符
      if(ch&0x80)
      {
       AfxMessageBox("含有中文字符");
       return;
      }
     }
     //返回的加密结果
     strResult = m_oDES.Encrypt(strTemp,strKey);
     poEdit = (CEdit*)GetDlgItem(IDC_EDITSTR2);
     poEdit->SetWindowText(strResult);
     //将上面获取的字符串数据转化为16进制数据
     Binary2Hex(reinterpret_cast<unsigned char*>(strResult.GetBuffer(0)),16,acHex);
     poEdit = (CEdit*)GetDlgItem(IDC_EDITHEX2);
     //显示结果
     poEdit->SetWindowText(acHex);
     //在IDC_LBLSTR上面显示刚刚加密的内容
     poStatic = (CStatic*)GetDlgItem(IDC_LBLSTR);
     poStatic->SetWindowText("DES加密的明文为:"+strTemp);
     //同时将上面的明文去除
     poEdit = (CEdit*)GetDlgItem(IDC_EDITALPHA);
     poEdit->SetWindowText("");
     break;
    case MD5:
     Binary2Hex(reinterpret_cast<unsigned char*>(acDigest), 16, acHex);
     iLength = 16;
     poEdit->SetWindowText(acHex);
     poEdit = (CEdit*)(GetDlgItem(IDC_EDITSTR2));
     //判别是否存在非法字符
     for(i=0; i<iLength; i++)
      if(acDigest[i] == 0)
       acDigest[i] = 0x0A;
     poEdit->SetWindowText(acDigest);
     break;
    case RSA:
     poEdit = (CEdit*)GetDlgItem(IDC_EDITP);
     poEdit->GetWindowText(strPrimeP);
     poEdit = (CEdit*)GetDlgItem(IDC_EDITQ);
     poEdit->GetWindowText(strPrimeQ);
     //判断输入的数据P、Q是否为素数
     if((!ToPrimeNumber(strPrimeP)) || (!ToPrimeNumber(strPrimeQ)))
      return;

    AfxMessageBox("采用RSA算法加密显示结果");
     iPrimeP = atoi(strPrimeP.GetBuffer(strPrimeP.GetLength()));
     iPrimeQ = atoi(strPrimeQ.GetBuffer(strPrimeQ.GetLength()));
     m_iRSAn = iPrimeP*iPrimeQ;
     //strTemp为加密的内容
     //调用CRSA类来进行加密
     iSubkey = m_oRSA.GetSecretKey(iPrimeP,iPrimeQ);
     //保存密钥,用于解密
     m_iRSAe = iSubkey;
     //显示密钥
     strKey.Format(_T("%d"),iSubkey);
     poStatic = (CStatic*)GetDlgItem(IDC_LBLSTR);
     poStatic->SetWindowText("RSA加密的密钥为:"+strKey);
     strResult = m_oRSA.Encrypt(strTemp,iPrimeP,iPrimeQ,iSubkey);
     //清空IDC_EDITALPHA里面的输入的明文
     poEdit = (CEdit*)GetDlgItem(IDC_EDITALPHA);
     poEdit->SetWindowText("");
     poEdit = (CEdit*)GetDlgItem(IDC_EDITSTR2);
     poEdit->SetWindowText(strResult);
     //将上面获取的字符串数据转化为16进制数据
     Binary2Hex(reinterpret_cast<unsigned char*>(strResult.GetBuffer(0)),16,acHex);
     poEdit = (CEdit*)GetDlgItem(IDC_EDITHEX2);
     //显示结果
     poEdit->SetWindowText(acHex);
     break;
   }
  }
  else//解密算法
  {
   m_iAction = DECRYPT;
   CString szDecyptResult,szDecyptMessage;
   switch(m_iMethod)
   {
    case DES:
     //显示解密的结果
     szDecyptResult = m_oDES.Decrypt();
     poEdit = (CEdit*)GetDlgItem(IDC_EDITALPHA);
     //显示解密的结果
     poEdit->SetWindowText(szDecyptResult);
     break;
    case MD5://解密按钮已经被屏蔽掉
     break;
    case RSA:
     AfxMessageBox("采用RSA算法解密显示结果");
     //获取解密的密文
     poEdit = (CEdit*)GetDlgItem(IDC_EDITSTR2);
     poEdit->GetWindowText(szDecyptMessage);
     szDecyptResult = m_oRSA.Decrypt(szDecyptMessage,m_iRSAe,m_iRSAn);
     poEdit = (CEdit*)GetDlgItem(IDC_EDITALPHA);
     poEdit->SetWindowText(szDecyptResult);
     break;
   } 
  }
}

//对输入的字符串进行转化
BOOL CEncryAndDecryptDlg::ToPrimeNumber(CString szTemp)
{
   //判别szTemp中是否有非数字的字符
   int iLength = szTemp.GetLength();
   for(int i = 0;i < iLength;i++)
   {
    char ch = szTemp.GetAt(i);
    if(!isdigit(ch))//不是数字
    {
     AfxMessageBox("输入的数据中含有非数字字符!");
     return  FALSE;
    }
   }
  //将CString字符串类转化为整形
   int INum = atoi(szTemp);
   if(!IsPrime(INum))//非素数处理
   {
   AfxMessageBox("输入的数据不是素数,请重试!");
    return  FALSE;
   }
  return TRUE;
}

//全局函数,用于判别输入的数据是否为素数
BOOL CEncryAndDecryptDlg::IsPrime(int x)
{
  int k;
  k = int(sqrt ( x ));
  for ( int i = 2; i <= k; i ++ )
  {
   if ( x % i == 0 )   
    break;
  }
  if ( i >= k + 1 )             
   return  TRUE;
  else
   return  FALSE;
}

假如那位想要代码,可以留下邮箱,我看到后会尽快发到你的邮箱里面。


关于我们 版权声明 广告服务 联系我们 友情链接 加入收藏
站长:施昌权    Email:scq2099yt@163.com    MSN:scq2099yt@live.cn    QQ:14046300    本站QQ群:67202409
Copyright © 2008     卓为VC(www.joyvc.cn)    All Rights Reserved    建议分辨率 1024×768
本站由施昌权制作维护
京ICP备09012297号