哪位有md5加密算法的c++代码实现,共享一下,谢谢

ryan_liz 2003-10-20 04:53:44
电邮:c0232@njupt.edu.cn
...全文
202 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
killme2008 2003-11-01
  • 打赏
  • 举报
回复
mark
TYKAO 2003-10-31
  • 打赏
  • 举报
回复
你好厉害啊~~~~~~~~~
不敢起真名 2003-10-31
  • 打赏
  • 举报
回复
真行
sham2k 2003-10-30
  • 打赏
  • 举报
回复
// 编码单个块(16x4=64 bytes)
void MD5::Transform(WORD32 * X)
{
#define F(x,y,z) (z ^ (x & (y^z)))
#define G(x,y,z) (y ^ (z & (x^y)))
#define H(x,y,z) (x ^ y ^ z)
#define I(x,y,z) (y ^ (x | ~z))

#define Subround(f,a,b,c,d,k,s,t) \
{ \
a += (k + t + f(b,c,d)); \
a = rotl((WORD32)(a), (unsigned int)(s)); \
a += b; \
}

unsigned long A,B,C,D;

A=digest[0];
B=digest[1];
C=digest[2];
D=digest[3];

/* Round 0 */
Subround(F,A,B,C,D,X[ 0], 7,0xd76aa478);
Subround(F,D,A,B,C,X[ 1],12,0xe8c7b756);
Subround(F,C,D,A,B,X[ 2],17,0x242070db);
Subround(F,B,C,D,A,X[ 3],22,0xc1bdceee);
Subround(F,A,B,C,D,X[ 4], 7,0xf57c0faf);
Subround(F,D,A,B,C,X[ 5],12,0x4787c62a);
Subround(F,C,D,A,B,X[ 6],17,0xa8304613);
Subround(F,B,C,D,A,X[ 7],22,0xfd469501);
Subround(F,A,B,C,D,X[ 8], 7,0x698098d8);
Subround(F,D,A,B,C,X[ 9],12,0x8b44f7af);
Subround(F,C,D,A,B,X[10],17,0xffff5bb1);
Subround(F,B,C,D,A,X[11],22,0x895cd7be);
Subround(F,A,B,C,D,X[12], 7,0x6b901122);
Subround(F,D,A,B,C,X[13],12,0xfd987193);
Subround(F,C,D,A,B,X[14],17,0xa679438e);
Subround(F,B,C,D,A,X[15],22,0x49b40821);

/* Round 1 */
Subround(G,A,B,C,D,X[ 1], 5,0xf61e2562);
Subround(G,D,A,B,C,X[ 6], 9,0xc040b340);
Subround(G,C,D,A,B,X[11],14,0x265e5a51);
Subround(G,B,C,D,A,X[ 0],20,0xe9b6c7aa);
Subround(G,A,B,C,D,X[ 5], 5,0xd62f105d);
Subround(G,D,A,B,C,X[10], 9,0x02441453);
Subround(G,C,D,A,B,X[15],14,0xd8a1e681);
Subround(G,B,C,D,A,X[ 4],20,0xe7d3fbc8);
Subround(G,A,B,C,D,X[ 9], 5,0x21e1cde6);
Subround(G,D,A,B,C,X[14], 9,0xc33707d6);
Subround(G,C,D,A,B,X[ 3],14,0xf4d50d87);
Subround(G,B,C,D,A,X[ 8],20,0x455a14ed);
Subround(G,A,B,C,D,X[13], 5,0xa9e3e905);
Subround(G,D,A,B,C,X[ 2], 9,0xfcefa3f8);
Subround(G,C,D,A,B,X[ 7],14,0x676f02d9);
Subround(G,B,C,D,A,X[12],20,0x8d2a4c8a);

/* Round 2 */
Subround(H,A,B,C,D,X[ 5], 4,0xfffa3942);
Subround(H,D,A,B,C,X[ 8],11,0x8771f681);
Subround(H,C,D,A,B,X[11],16,0x6d9d6122);
Subround(H,B,C,D,A,X[14],23,0xfde5380c);
Subround(H,A,B,C,D,X[ 1], 4,0xa4beea44);
Subround(H,D,A,B,C,X[ 4],11,0x4bdecfa9);
Subround(H,C,D,A,B,X[ 7],16,0xf6bb4b60);
Subround(H,B,C,D,A,X[10],23,0xbebfbc70);
Subround(H,A,B,C,D,X[13], 4,0x289b7ec6);
Subround(H,D,A,B,C,X[ 0],11,0xeaa127fa);
Subround(H,C,D,A,B,X[ 3],16,0xd4ef3085);
Subround(H,B,C,D,A,X[ 6],23,0x04881d05);
Subround(H,A,B,C,D,X[ 9], 4,0xd9d4d039);
Subround(H,D,A,B,C,X[12],11,0xe6db99e5);
Subround(H,C,D,A,B,X[15],16,0x1fa27cf8);
Subround(H,B,C,D,A,X[ 2],23,0xc4ac5665);

/* Round 3 */
Subround(I,A,B,C,D,X[ 0], 6,0xf4292244);
Subround(I,D,A,B,C,X[ 7],10,0x432aff97);
Subround(I,C,D,A,B,X[14],15,0xab9423a7);
Subround(I,B,C,D,A,X[ 5],21,0xfc93a039);
Subround(I,A,B,C,D,X[12], 6,0x655b59c3);
Subround(I,D,A,B,C,X[ 3],10,0x8f0ccc92);
Subround(I,C,D,A,B,X[10],15,0xffeff47d);
Subround(I,B,C,D,A,X[ 1],21,0x85845dd1);
Subround(I,A,B,C,D,X[ 8], 6,0x6fa87e4f);
Subround(I,D,A,B,C,X[15],10,0xfe2ce6e0);
Subround(I,C,D,A,B,X[ 6],15,0xa3014314);
Subround(I,B,C,D,A,X[13],21,0x4e0811a1);
Subround(I,A,B,C,D,X[ 4], 6,0xf7537e82);
Subround(I,D,A,B,C,X[11],10,0xbd3af235);
Subround(I,C,D,A,B,X[ 2],15,0x2ad7d2bb);
Subround(I,B,C,D,A,X[ 9],21,0xeb86d391);

digest[0]+=A;
digest[1]+=B;
digest[2]+=C;
digest[3]+=D;
}



/* MD5 算法介绍

MD5的全称是Message-Digest Algorithm 5,在90年代初由MIT的计算机科学实验室
和RSA Data Security Inc发明,经MD2、MD3和MD4发展而来。Message-Digest泛指字节串
(Message)的Hash变换,就是把一个任意长度的字节串变换成一定长的大整数。请注意
我使用了“字节串”而不是“字符串”这个词,是因为这种变换只与字节的值有关,与
字符集或编码方式无关。MD5将任意长度的“字节串”变换成一个128bit的大整数,并且
它是一个不可逆的字符串变换算法。换句话说就是,即使你看到源程序和算法描述,也
无法将一个MD5的值变换回原始的字符串,从数学原理上说,是因为原始的字符串有无穷
多个,这有点象不存在反函数的数学函数。

MD5的典型应用是对一段Message(字节串)产生fingerprint(指纹),以防止被“篡改”。
举个例子,你将一段话写在一个叫readme.txt文件中,并对这个readme.txt产生一个MD5的
值并记录在案,然后你可以传播这个文件给别人,别人如果修改了文件中的任何内容,你对
这个文件重新计算MD5时就会发现。如果再有一个第三方的认证机构,用MD5还可以防止文件
作者的“抵赖”,这就是所谓的数字签名应用。

MD5还广泛用于加密和解密技术上,在很多操作系统中,用户的密码是以MD5值(或类似
的其它算法)的方式保存的,用户Login的时候,系统是把用户输入的密码计算成MD5值,然
后再去和系统中保存的MD5值进行比较,而系统并不“知道”用户的密码是什么。

MD5算法:

第一步:增加填充

增加padding使得数据长度(bit为单位)模512为448。
如果数据长度正好是模512为448,增加512个填充bit,也就是说填充的个数为1-512。
第一个bit为1,其余全部为0。(即第一个字节为0x80)

第二步:补足长度

将数据长度转换为64bit的数值,如果长度超过64bit所能表示的数据长度的范围,值保留最后64bit,
增加到前面填充的数据后面,使得最后的数据为512bit的整数倍。也就是32bit的16倍的整数倍。
在RFC1321中,32bit称为一个word。

第三步:初始化变量:

用到4个变量,分别为A、B、C、D,均为32bit长。初始化为:
A: 01 23 45 67
B: 89 ab cd ef
C: fe dc ba 98
D: 76 54 32 10

第四步:数据处理:

首先定义4个辅助函数:
F(X,Y,Z) = XY v not(X) Z
G(X,Y,Z) = XZ v Y not(Z)
H(X,Y,Z) = X xor Y xor Z
I(X,Y,Z) = Y xor (X v not(Z))
其中:XY表示按位与,X v Y表示按位或,not(X)表示按位取反。xor表示按位异或。
函数中的X、Y、Z均为32bit。
定义一个需要用到的数组:T(i),i取值1-64,T(i)等于abs(sin(i))的4294967296倍的整数部分,i为弧度。

第五步:输出:

最后得到的ABCD为输出结果,共128bit。A为低位,D为高位。

补充说明:

MD5使用四个32位整数作为计算基础和计算结果,因此消息摘要长度=4x32=128位
MD5每次处理16个32位整数,分四个圈替换完成,块大小为16x32/8=64字节,即64x8=512位
如果输入的长度不足64字节,则需要填充0x80,0x00,0x00,0x00..,其中最后一个块的14(56 57 58 59)
15(60 61 62 63)字节分别为输入消息的总位数=字节数x8,因此最后一个块的填充长度=64-8=56-前次
剩余的长度.如果前次剩余长度>56,则多添一个块。
最后由于主机cpu可能是低位在前,也可能是高位在前,因此需要转换成低位在前,计算结果再转换回来.

A B C D D C B A
1 2 3 4 ---> 4 3 2 1
--------- ---------
A1B2C3D4 D4C3B2A1 --> A1B2C3D4
*/
sham2k 2003-10-30
  • 打赏
  • 举报
回复
这是从网上找到的,我略加修改

//-------------------------------------------------------------------//
// MD5加密类 Version 1.0 //
// //
// Create: 2003-10-08 Modify: 2003-10-08 Complete: //
// //
//-------------------------------------------------------------------//
#ifndef __MD5__
#define __MD5__

#include "common.hpp"
#include "cstring.hpp"

typedef unsigned char BYTE;
typedef unsigned long WORD32;

// 离散算法类
class Hash
{
protected:
void CorrectEndianess(WORD32 * out, const WORD32 * in, unsigned int byteCount);
WORD32 byteReverse(WORD32 value);
void byteReverse(WORD32 * out,const WORD32 * in, unsigned int byteCount);

int nKeySize; // 输出离散值长度
virtual void Init() = 0; // 初始化离散函数
virtual void Update(BYTE * InBuff,WORD32 nSize) = 0; // 分段计算离散值
virtual void Final(BYTE * OutBuff) = 0; // 结束处理

public:
CString HashBuffer(BYTE * InBuffer,unsigned long nInSize);
CString HashFile(const char * sFileName,unsigned long nSkipSize=0,unsigned long nMaxReadSize=0);
};

// MD5离散类
class MD5:public Hash
{
private:
BYTE buffer[64]; // 内部工作区
WORD32 digest[4]; // 离散值
WORD32 nCount[2]; // 总位数

void Init();
void Update(BYTE * InBuff,WORD32 nSize);
void Final(BYTE * OutBuff);
void Transform(WORD32 * x);

public:
MD5() { Init(); }
~MD5() {}
};

#endif



//-------------------------------------------------------------------//
// MD5离散函数类 Version 1.0 //
// //
// Create: 2003-10-08 Modify: 2003-10-08 Complete: 2003-10-09 //
// //
//-------------------------------------------------------------------//

// Version changed:
//
// 2003-10-08 LNY Create
// 2003-10-09 LNY Complete Version 1.0
//

#include <stdio.h>
#include <memory.h>
#include <stdlib.h>

#include "commfunction.hpp"
#include "md5.hpp"

#ifdef WIN32
#define rotl(a,s) _rotl(a,s)
#else
#define rotl(v,n) (((v)<<(n))|((v)>>(32-(n))))
#endif

// Hash
//
// 2003-10-09 LNY CString Hash::HashBuffer(BYTE * InBuffer,unsigned long nInSize)
// 2003-10-09 LNY CString Hash::HashFile(const char * sFileName)
// 2003-10-09 LNY inline WORD32 Hash::byteReverse(WORD32 value)
// 2003-10-09 LNY inline void Hash::byteReverse(WORD32 * out,const WORD32 * in, unsigned int byteCount)
// 2003-10-09 LNY inline void Hash::CorrectEndianess(WORD32 *out, const WORD32 *in, unsigned int byteCount)
// 2003-10-09 LNY inline void Hash::CorrectEndianess(WORD32 *out, const WORD32 *in, unsigned int byteCount)
//

// 交换WORD32高低位(低位在前)
inline WORD32 Hash::byteReverse(WORD32 value)
{
value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
return rotl(value,16);
}

// 交换一段内容高低位(低位在前)
inline void Hash::byteReverse(WORD32 * out,const WORD32 * in, unsigned int byteCount)
{
byteCount /= sizeof(WORD32);
for (unsigned i=0; i<byteCount; i++) out[i] = byteReverse(in[i]);
}

// 进行字节校正(低位在前)
inline void Hash::CorrectEndianess(WORD32 *out, const WORD32 *in, unsigned int byteCount)
{
#ifndef WIN32
byteReverse(out,in,byteCount);
#else
if (in!=out) memcpy(out,in,byteCount);
#endif
}

// 计算一段内存的离散值
CString Hash::HashBuffer(BYTE * InBuffer,WORD32 nInSize)
{
Init();
Update(InBuffer,nInSize);
CString sWrkStr;
Final((BYTE*)sWrkStr.GetBufferSetLength(nKeySize));
return BinToHex((BYTE *)sWrkStr.GetBuffer(0),nKeySize);
}

// 计算文件
CString Hash::HashFile(const char * sFileName,unsigned long nSkipSize,unsigned long nMaxReadSize)
{
BYTE buffer[10240];
unsigned int nReadSize;

FILE * fp;
fp=fopen(sFileName,"rb");
if(fp==NULL) return "";
fseek(fp,nSkipSize,SEEK_SET);

Init();
while(1)
{
nReadSize = (nMaxReadSize>10240)? 10240:nMaxReadSize;
nReadSize = fread(buffer,1,nReadSize,fp);
if(nReadSize < 0)
{
fclose(fp);
return "";
}
Update(buffer,nReadSize);
if(nReadSize < 10240) break;
if(nMaxReadSize>0) nMaxReadSize -= nReadSize;
}
fclose(fp);

CString sWrkStr;
Final((BYTE*)sWrkStr.GetBufferSetLength(nKeySize));
return BinToHex((BYTE *)sWrkStr.GetBuffer(0),nKeySize);
}

// MD5
//
// 2003-10-09 LNY void MD5::Init()
// 2003-10-09 LNY void MD5::Update(BYTE * InBuffer,WORD32 nSize)
// 2003-10-09 LNY void MD5::Final(BYTE * OutBuffer)
// 2003-10-09 LNY void MD5::Transform(WORD32 * X)
//

// MD5 初始化
void MD5::Init()
{
nKeySize = sizeof(digest); // 4x4=16x8=128 bits
nCount[0] = nCount[1] = 0;
digest[0] = 0x67452301;
digest[1] = 0xefcdab89;
digest[2] = 0x98badcfe;
digest[3] = 0x10325476;
memset(buffer,0,sizeof(buffer));
}

// MD5 编码一段数据
void MD5::Update(BYTE * InBuffer,WORD32 nSize)
{
unsigned int i,index,partLen;

index = ((nCount[0]>>3) & 0x3F); // 前次模64后剩余字节数
nCount[0] += (nSize << 3); // 累加总位数低位(字节数x8)
nCount[1] += (nSize >> 29); // 累加总位数高位
if (nCount[0]<(nSize<<3)) nCount[1] ++; // 低位发生溢出,高位进位

partLen = 64 - index;
if (nSize >= partLen)
{
memcpy((BYTE *)buffer + index,InBuffer,partLen);
CorrectEndianess((WORD32 *)buffer,(WORD32 *) buffer,64); // 校正字节高低位
Transform((WORD32 *)buffer); // 先转换前次剩余的+本次补充的
for (i=partLen;i+63<nSize;i+=64) // 再每次处理64字节
{
CorrectEndianess((WORD32 *)buffer,(WORD32 *)&InBuffer[i],64); // 校正
Transform((WORD32 *)buffer);
}
index = 0;
}
else i = 0;

// 将剩余的留到下次处理
memcpy(buffer + index,InBuffer + i,nSize - i);
}

// 结束处理(填充)
void MD5::Final(BYTE * OutBuffer)
{
int index;
index = ((nCount[0]>>3) & 0x3f); // 模64剩余的字节数
if(index > 56) // 56 = 64-8 = 64 - nCount
{
// 填充0x80,0x00,0x00,0x00...
memset(buffer + index,0x0 ,64-index); // 填充 0x0
buffer[index] = 0x80;
CorrectEndianess((WORD32 *)buffer,(WORD32 *) buffer,64); // 校正
Transform((WORD32 *)buffer);

// 添加总位数到56-63
memset(buffer, 0x0,64);
memcpy(buffer + 56,&nCount,sizeof(nCount)); // 全零,不必校正
Transform((WORD32 *)buffer);
}
else
{
// 填充0x80,0x00,0x00,0x00...
memset(buffer + index,0x0 ,64-index); // 填充 0x0
buffer[index] = 0x80;
CorrectEndianess((WORD32 *)buffer,(WORD32 *) buffer,56); // 校正

// 添加总位数到56-63
memcpy(buffer + 56,&nCount,sizeof(nCount)); // 本身是低位在前,不必校正
Transform((WORD32 *)buffer);
}

// Get the digest value
CorrectEndianess((WORD32 *)&digest,(WORD32 *)&digest,sizeof(digest)); // 结果也需要校正
memcpy(OutBuffer,&digest,sizeof(digest));

Init(); // for next use
}

likeforever 2003-10-29
  • 打赏
  • 举报
回复
晕,是想要晕了,忘了写地址,like-forever@163.com
likeforever 2003-10-29
  • 打赏
  • 举报
回复
我也要,能不能给我啊
谢谢谢谢谢谢谢谢谢谢谢谢
ProgrameMan 2003-10-29
  • 打赏
  • 举报
回复
cygroup@163.net 给我一份好吗 很急的谢谢
coobby 2003-10-21
  • 打赏
  • 举报
回复
coobby@sh163.net
谢谢!
Aydge 2003-10-21
  • 打赏
  • 举报
回复
aydge@ynmail.com也来一份吧
daizh 2003-10-20
  • 打赏
  • 举报
回复
我发给你了

24,854

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 工具平台和程序库
社区管理员
  • 工具平台和程序库社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧