注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

fancye的博客

 
 
 

日志

 
 

VC++的MD5代码  

2012-05-14 10:18:14|  分类: Vc |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
转自:http://hi.baidu.com/120680451/blog/item/f8f1d8fcd600e31c09244df8.html

    做一个加密程序,要用到MD5,在网上找了很久,要不是代码不能在VC++下通过,就是求出来的MD5不对,上百度查出来的求MD5的方法,实在是太那个什么了,很多细节都没说清楚。最后没办法,找到了MD5的英文原文文档,再加上一个伪代码,还是自己研究比较妥当。

Md5.h:

// Md5.h: interface for the CMd5 class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_MD5_H__1A63D260_C069_48D7_A1A1_FF1FA02552C7__INCLUDED_)
#define AFX_MD5_H__1A63D260_C069_48D7_A1A1_FF1FA02552C7__INCLUDED_

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

class CMd5
{
public:
CString getStringMd5(CString srcstring);
CString getFileMd5(CString filename);
CMd5();
virtual ~CMd5();

private:
CString getMd5();
unsigned char *m_cSrcString;//存放填充后的数据
DWORD w[16];//每一轮放子组信息
ULONGLONG m_uLength;//填充后的总长度
int r[64];
DWORD k[64];
DWORD h0, h1, h2, h3;
DWORD leftrotate(DWORD x, int c);
};

#endif // !defined(AFX_MD5_H__1A63D260_C069_48D7_A1A1_FF1FA02552C7__INCLUDED_)

Md5.cpp:

// Md5.cpp: implementation of the CMd5 class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Md5.h"
#include <Math.h>

#define PI 3.1415926535

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

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CMd5::CMd5()
{
m_cSrcString = NULL;
int rr[64] = { 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
      5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
      4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
      6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21};
for(int i=0;i<64;i++)
{
   r[i] = rr[i];
   double j = sin(i+1);
   if(j<0) j = -1 * j;
   k[i] = j * (pow(2,32));
}
}

CMd5::~CMd5()
{
}


CString CMd5::getMd5()
{
h0 = 0x67452301;
h1 = 0xEFCDAB89;
h2 = 0x98BADCFE;
h3 = 0x10325476;
DWORD f, g, temp;;
DWORD a, b, c, d;
for(int j=0;j<m_uLength/64;j++)
{
   a = h0; b = h1; c = h2; d = h3;
   for(int i=0;i<16;i++) memmove(&w[i],&m_cSrcString[j*64+i*4],4);

/*  
   CString str,tm;
   str.Format("\n\nw[0]-w[15]的16进制值是:\n");
   for(i=0;i<16;i++)
   {
    tm.Format("0x%0x ",w[i]);
    str += tm;
   }
   AfxMessageBox(str);
*/
  
   for(i=0;i<64;i++)
   {
    if(i>=0 && i<=15)
    {
     f = (b & c) | ((~b) & d);
     g = i;
    }
    else if(i>=16 && i<=31)
    {
     f = (d & b) | ((~d) & c);
     g = (5 * i +1) % 16;
    }
    else if(i>=32 && i<=47)
    {
     f = b ^ c ^ d;
     g = (3 * i + 5) % 16;
    }
    else if(i>=48 && i<=63)
    {
     f = c ^ ( b | ( ~d ) );
     g = (7 * i) % 16;
    }
    temp = d;
    d = c;
    c = b;
    b = b + leftrotate((a + f + k[i] + w[g]), r[i]);
    a = temp;
   }
   h0 += a;
   h1 += b;
   h2 += c;
   h3 += d;
}

if(m_cSrcString!=NULL)
{
   delete m_cSrcString;
   m_cSrcString = NULL;
}
CString result,t;
result.Empty();
unsigned char ch[16];
memmove(&ch[0], &h0, 4);
memmove(&ch[4], &h1, 4);
memmove(&ch[8], &h2, 4);
memmove(&ch[12], &h3, 4);
for(int i=0;i<16;i++)
{
   t.Format("%02x",ch[i]);
   result += t;
}
return result;
}

DWORD CMd5::leftrotate(DWORD x, int c)
{
return ((x << c) | x >> (32-c));
}

CString CMd5::getFileMd5(CString filename)
{
ULONGLONG strlen;
CFile file(filename, CFile::typeBinary | CFile::modeRead);
strlen = file.GetLength(); /////////////////////////////////strlen为加密字符串的本身长度
if((strlen % 64) < 56) m_uLength = ((strlen / 64) + 1) * 64;
else m_uLength = ((strlen / 64) + 2) * 64;   //////////////m_uLength为填充后的长度
m_cSrcString = new unsigned char [m_uLength];
file.Read(m_cSrcString, m_uLength);
file.Close();
m_cSrcString[strlen] &= 0x80;
for(int i=strlen+1;i<m_uLength;i++)
   m_cSrcString[i] &= 0x0;
strlen *= 8;
memmove(&m_cSrcString[m_uLength-8], &strlen, 8);
return getMd5();
}

CString CMd5::getStringMd5(CString srcstring)
{
ULONGLONG strlen;
strlen = srcstring.GetLength(); /////////////////////////////////strlen为加密字符串的本身长度
if((strlen % 64) < 56) m_uLength = ((strlen / 64) + 1) * 64;
else m_uLength = ((strlen / 64) + 2) * 64;   //////////////m_uLength为填充后的长度
m_cSrcString = new unsigned char [m_uLength];
memmove(m_cSrcString, srcstring, strlen);
m_cSrcString[strlen] &= 0x80;
for(int i=strlen+1;i<m_uLength;i++)
   m_cSrcString[i] &= 0x0;
strlen *= 8;
memmove(&m_cSrcString[m_uLength-8], &strlen, 8);
return getMd5();


   /////////////////////////////////////////////////////////用于测试检查是否出错

/*

CString t1,t2;
t1 = str;
str.Empty();
for(i=0;i<m_uLength;i++)
{
   t2.Format("0x%0x ",m_cSrcString[i]);
   str += t2;
}
t1.Format("原来的字符串为:%s\n\n填充的字符串为:%s\n\n原来的长度为:%ld\n\n",
   t1,m_cSrcString,strlen);
t2.Format("改后的长度为:%d\n\n16进制显示:",m_uLength);
str = t1 + t2 + str;
AfxMessageBox(str);
*/

}

  评论这张
 
阅读(73)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018