VC实现数据的加密和解密(MD5加密/DES/RSA加密解密)
发布日期:2021-10-16 12:05:22 浏览次数:12 分类:技术文章

本文共 49351 字,大约阅读时间需要 164 分钟。

   

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

//测试判别:摘自

/*
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();
};
//具体的函数可以参考 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;
}

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

 对了,怎么能够上传代码和图片啊???

转载地址:https://blog.csdn.net/snowbirdfly/article/details/1325783 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:国外著名大学计算机教学考察随笔
下一篇:【社招】【NVIDIA】英伟达2019新年热招职位 给你寒冬不一样的温暖

发表评论

最新留言

留言是一种美德,欢迎回访!
[***.207.175.100]2024年04月24日 16时51分19秒