📄 md5算法原理.txt
字号:
/* 第2轮* */
/* 以 [abcd k s i]表示如下操作
a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
/* Do the following 16 operations. */
[ABCD 1 5 17] [DABC 6 9 18] [CDAB 11 14 19] [BCDA
0 20 20]
[ABCD 5 5 21] [DABC 10 9 22] [CDAB 15 14 23]
[BCDA 4 20 24]
[ABCD 9 5 25] [DABC 14 9 26] [CDAB 3 14 27] [BCDA
8 20 28]
[ABCD 13 5 29] [DABC 2 9 30] [CDAB 7 14 31] [BCDA
12 20 32]
/* 第3轮*/
/* 以 [abcd k s i]表示如下操作
a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
/* Do the following 16 operations. */
[ABCD 5 4 33] [DABC 8 11 34] [CDAB 11 16 35]
[BCDA 14 23 36]
[ABCD 1 4 37] [DABC 4 11 38] [CDAB 7 16 39] [BCDA
10 23 40]
[ABCD 13 4 41] [DABC 0 11 42] [CDAB 3 16 43]
[BCDA 6 23 44]
[ABCD 9 4 45] [DABC 12 11 46] [CDAB 15 16 47]
[BCDA 2 23 48]
/* 第4轮*/
/* 以 [abcd k s i]表示如下操作
a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
/* Do the following 16 operations. */
[ABCD 0 6 49] [DABC 7 10 50] [CDAB 14 15 51]
[BCDA 5 21 52]
[ABCD 12 6 53] [DABC 3 10 54] [CDAB 10 15 55]
[BCDA 1 21 56]
[ABCD 8 6 57] [DABC 15 10 58] [CDAB 6 15 59]
[BCDA 13 21 60]
[ABCD 4 6 61] [DABC 11 10 62] [CDAB 2 15 63]
[BCDA 9 21 64]
/* 然后进行如下操作 */
A = A + AA
B = B + BB
C = C + CC
D = D + DD
end /* 结束对I的循环*/
输出结果。
//-------------------------------------------------------------------//
// 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
#include
#include
#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}
// 进行字节校正(低位在前)
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 {
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
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -