MD5是用于确保信息传输完整一致性的一个哈希算法。
其算法思想如下(摘自维基百科):
MD5是输入不定长度信息,输出固定长度128-bits的算法。经过程序流程,生成四个32位数据,最后联合起来成为一个128-bits。基本方式为,求余、取余、调整长度、与链接变量进行循环运算。得出结果。
一个MD5运算— 由类似的64次循环构成,分成4组16次。F 一个非线性函数;一个函数运算一次。Mi 表示一个 32-bits 的输入数据,Ki表示一个 32-bits 常数,用来完成每次不同的计算。
下面是AMPS中MD5模块的源码(说真的,算法细节上还没完全理解清楚)
AMPS_MD5.h
#ifndef __HEADER_AMPS_MD5_H
#define __HEADER_AMPS_MD5_H
#ifdef __cplusplus
extern "C" {
#endif
#include "AMPS_Defines.h"
#include "AMPS_LinkList.h"
typedef struct _AMPSMD5Context t_AMPSMD5Context;
struct _AMPSMD5Context
{
unsigned int punTotal[2];
unsigned int punState[4];
unsigned char puchBuffer[64];
};
void* AMD5_Init(void* r_pvAMPSContext);
void AMD5_Cleanup(void* r_pvAMPSContext, void* r_pvAMPSMD5Context);
int AMD5_Update(void* r_pvAMPSContext, void* r_pvAMPSMD5Context, unsigned char* r_puchData, int r_nDataLength);
int AMD5_Final(void* r_pvAMPSContext, void* r_pvAMPSMD5Context, unsigned char* r_puchMD5Hash);
#ifdef __cplusplus
}
#endif
#endif //__HEADER_AMPS_HEAP_H
AMPS_MD5.c
#include "AMPS_Core.h"
#include "AMPS_Defines.h"
#include "AMPS_MemMgt.h"
#include "AMPS_MD5.h"
#include "AMPS_LinkList.h"
#define GET_UINT32(n,b,i) \
{ \
(n) = ( (unsigned int) (b)[(i) ] ) \
| ( (unsigned int) (b)[(i) + 1] << 8 ) \
| ( (unsigned int) (b)[(i) + 2] << 16 ) \
| ( (unsigned int) (b)[(i) + 3] << 24 ); \
}
#define PUT_UINT32(n,b,i) \
{ \
(b)[(i) ] = (unsigned char) ( (n) ); \
(b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
(b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
(b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
}
/*****************************************************************
函数名称: AMD5_Init
功能描述: MD5模块初始化
入参::
void* r_pvAMPSContext AMPS应用上下文
出参:
返回值:
int
*****************************************************************/
void* AMD5_Init(void* r_pvAMPSContext)
{
t_AMPSMD5Context* poAMPSMD5Context = NULL;
TRACE( MD5_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n");
poAMPSMD5Context = (t_AMPSMD5Context*)AMPS_InternalMalloc(sizeof(t_AMPSMD5Context));
if(NULL == poAMPSMD5Context)
{
TRACE( MD5_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "AMPS_InternalMalloc failed for poMD5Context.\n");
return NULL;
}
poAMPSMD5Context->punTotal[0] = 0;
poAMPSMD5Context->punTotal[1] = 0;
/*四个32位被称作链接变量*/
poAMPSMD5Context->punState[0] = 0x67452301;
poAMPSMD5Context->punState[1] = 0xEFCDAB89;
poAMPSMD5Context->punState[2] = 0x98BADCFE;
poAMPSMD5Context->punState[3] = 0x10325476;
TRACE( MD5_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving.\n");
return poAMPSMD5Context;
}
/*****************************************************************
函数名称: AMD5_Cleanup
功能描述: MD5模块销毁
入参::
void* r_pvAMPSContext AMPS应用上下文
void* r_pvAMPSMD5Context MD5句柄
出参:
返回值:
int
*****************************************************************/
void AMD5_Cleanup(void* r_pvAMPSContext, void* r_pvAMPSMD5Context)
{
TRACE( MD5_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n");
TRACE( MD5_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_DEBUG, "AMPS_InternalFree called for r_pvAMPSMD5Context.\n");
AMPS_InternalFree(r_pvAMPSMD5Context);
TRACE( MD5_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving.\n");
}
/*****************************************************************
函数名称: AMD4_Process
功能描述: MD4处理过程
入参::
void* r_pvAMPSContext AMPS应用上下文
void* r_pvAMPSMD5Context MD5句柄
unsigned char r_puchData[64] 64位二进制表示的填充信息
出参:
返回值:
int
*****************************************************************/
void AMD4_Process(void* r_pvAMPSContext, void* r_pvAMPSMD5Context, unsigned char r_puchData[64])
{
t_AMPSMD5Context* poAMPSMD5Context = r_pvAMPSMD5Context;
unsigned int X[16], A, B, C, D;
TRACE( MD5_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n");
GET_UINT32( X[0], r_puchData, 0 );
GET_UINT32( X[1], r_puchData, 4 );
GET_UINT32( X[2], r_puchData, 8 );
GET_UINT32( X[3], r_puchData, 12 );
GET_UINT32( X[4], r_puchData, 16 );
GET_UINT32( X[5], r_puchData, 20 );
GET_UINT32( X[6], r_puchData, 24 );
GET_UINT32( X[7], r_puchData, 28 );
GET_UINT32( X[8], r_puchData, 32 );
GET_UINT32( X[9], r_puchData, 36 );
GET_UINT32( X[10], r_puchData, 40 );
GET_UINT32( X[11], r_puchData, 44 );
GET_UINT32( X[12], r_puchData, 48 );
GET_UINT32( X[13], r_puchData, 52 );
GET_UINT32( X[14], r_puchData, 56 );
GET_UINT32( X[15], r_puchData, 60 );
#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
/*计算公式*/
#define P(a,b,c,d,k,s,t) \
{ \
a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
}
A = poAMPSMD5Context->punState[0];
B = poAMPSMD5Context->punState[1];
C = poAMPSMD5Context->punState[2];
D = poAMPSMD5Context->punState[3];
/*第一轮*/
#define F(x,y,z) (z ^ (x & (y ^ z)))
P( A, B, C, D, 0, 7, 0xD76AA478 );
P( D, A, B, C, 1, 12, 0xE8C7B756 );
P( C, D, A, B, 2, 17, 0x242070DB );
P( B, C, D, A, 3, 22, 0xC1BDCEEE );
P( A, B, C, D, 4, 7, 0xF57C0FAF );
P( D, A, B, C, 5, 12, 0x4787C62A );
P( C, D, A, B, 6, 17, 0xA8304613 );
P( B, C, D, A, 7, 22, 0xFD469501 );
P( A, B, C, D, 8, 7, 0x698098D8 );
P( D, A, B, C, 9, 12, 0x8B44F7AF );
P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
P( B, C, D, A, 11, 22, 0x895CD7BE );
P( A, B, C, D, 12, 7, 0x6B901122 );
P( D, A, B, C, 13, 12, 0xFD987193 );
P( C, D, A, B, 14, 17, 0xA679438E );
P( B, C, D, A, 15, 22, 0x49B40821 );
#undef F
/*第二轮*/
#define F(x,y,z) (y ^ (z & (x ^ y)))
P( A, B, C, D, 1, 5, 0xF61E2562 );
P( D, A, B, C, 6, 9, 0xC040B340 );
P( C, D, A, B, 11, 14, 0x265E5A51 );
P( B, C, D, A, 0, 20, 0xE9B6C7AA );
P( A, B, C, D, 5, 5, 0xD62F105D );
P( D, A, B, C, 10, 9, 0x02441453 );
P( C, D, A, B, 15, 14, 0xD8A1E681 );
P( B, C, D, A, 4, 20, 0xE7D3FBC8 );
P( A, B, C, D, 9, 5, 0x21E1CDE6 );
P( D, A, B, C, 14, 9, 0xC33707D6 );
P( C, D, A, B, 3, 14, 0xF4D50D87 );
P( B, C, D, A, 8, 20, 0x455A14ED );
P( A, B, C, D, 13, 5, 0xA9E3E905 );
P( D, A, B, C, 2, 9, 0xFCEFA3F8 );
P( C, D, A, B, 7, 14, 0x676F02D9 );
P( B, C, D, A, 12, 20, 0x8D2A4C8A );
#undef F
/*第三轮*/
#define F(x,y,z) (x ^ y ^ z)
P( A, B, C, D, 5, 4, 0xFFFA3942 );
P( D, A, B, C, 8, 11, 0x8771F681 );
P( C, D, A, B, 11, 16, 0x6D9D6122 );
P( B, C, D, A, 14, 23, 0xFDE5380C );
P( A, B, C, D, 1, 4, 0xA4BEEA44 );
P( D, A, B, C, 4, 11, 0x4BDECFA9 );
P( C, D, A, B, 7, 16, 0xF6BB4B60 );
P( B, C, D, A, 10, 23, 0xBEBFBC70 );
P( A, B, C, D, 13, 4, 0x289B7EC6 );
P( D, A, B, C, 0, 11, 0xEAA127FA );
P( C, D, A, B, 3, 16, 0xD4EF3085 );
P( B, C, D, A, 6, 23, 0x04881D05 );
P( A, B, C, D, 9, 4, 0xD9D4D039 );
P( D, A, B, C, 12, 11, 0xE6DB99E5 );
P( C, D, A, B, 15, 16, 0x1FA27CF8 );
P( B, C, D, A, 2, 23, 0xC4AC5665 );
#undef F
/*第四轮*/
#define F(x,y,z) (y ^ (x | ~z))
P( A, B, C, D, 0, 6, 0xF4292244 );
P( D, A, B, C, 7, 10, 0x432AFF97 );
P( C, D, A, B, 14, 15, 0xAB9423A7 );
P( B, C, D, A, 5, 21, 0xFC93A039 );
P( A, B, C, D, 12, 6, 0x655B59C3 );
P( D, A, B, C, 3, 10, 0x8F0CCC92 );
P( C, D, A, B, 10, 15, 0xFFEFF47D );
P( B, C, D, A, 1, 21, 0x85845DD1 );
P( A, B, C, D, 8, 6, 0x6FA87E4F );
P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
P( C, D, A, B, 6, 15, 0xA3014314 );
P( B, C, D, A, 13, 21, 0x4E0811A1 );
P( A, B, C, D, 4, 6, 0xF7537E82 );
P( D, A, B, C, 11, 10, 0xBD3AF235 );
P( C, D, A, B, 2, 15, 0x2AD7D2BB );
P( B, C, D, A, 9, 21, 0xEB86D391 );
#undef F
poAMPSMD5Context->punState[0] += A;
poAMPSMD5Context->punState[1] += B;
poAMPSMD5Context->punState[2] += C;
poAMPSMD5Context->punState[3] += D;
TRACE( MD5_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving.\n");
}
/*****************************************************************
函数名称: AMD5_Update
功能描述: MD5处理过程
入参::
void* r_pvAMPSContext AMPS应用上下文
void* r_pvAMPSMD5Context MD5句柄
unsigned char r_puchData[64] 64位二进制表示的填充信息
int r_nDataLength 数据长度
出参:
返回值:
int
*****************************************************************/
int AMD5_Update(void* r_pvAMPSContext, void* r_pvAMPSMD5Context, unsigned char* r_puchData, int r_nDataLength)
{
t_AMPSMD5Context* poAMPSMD5Context = r_pvAMPSMD5Context;
unsigned int left, fill;
TRACE( MD5_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n");
if( ! r_nDataLength ) return AMPS_ERROR_FAILURE;
left = poAMPSMD5Context->punTotal[0] & 0x3F;
fill = 64 - left;
poAMPSMD5Context->punTotal[0] += r_nDataLength;
poAMPSMD5Context->punTotal[0] &= 0xFFFFFFFF;
if( poAMPSMD5Context->punTotal[0] < (unsigned int)r_nDataLength )
poAMPSMD5Context->punTotal[1]++;
if( left && (unsigned int)r_nDataLength >= fill )
{
memcpy((void*)(poAMPSMD5Context->puchBuffer + left), (void*)r_puchData, fill );
AMD4_Process(r_pvAMPSContext, poAMPSMD5Context, poAMPSMD5Context->puchBuffer );
r_nDataLength -= fill;
r_puchData += fill;
left = 0;
}
while( r_nDataLength >= 64 )
{
AMD4_Process(r_pvAMPSContext, poAMPSMD5Context, r_puchData);
r_nDataLength -= 64;
r_puchData += 64;
}
if( r_nDataLength )
{
memcpy((void*)(poAMPSMD5Context->puchBuffer + left), (void*)r_puchData, r_nDataLength );
}
TRACE( MD5_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving.\n");
return AMPS_SUCCESS;
}
/*64位填充信息*/
static unsigned char md5_padding[64] =
{
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/*****************************************************************
函数名称: AMD5_Final
功能描述: MD5计算函数
入参::
void* r_pvAMPSContext AMPS应用上下文
void* r_pvAMPSMD5Context MD5句柄
unsigned char* r_puchMD5Hash md5值
出参:
unsigned char* r_puchMD5Hash md5值
返回值:
int
*****************************************************************/
int AMD5_Final(void* r_pvAMPSContext, void* r_pvAMPSMD5Context, unsigned char* r_puchMD5Hash)
{
t_AMPSMD5Context* poAMPSMD5Context = r_pvAMPSMD5Context;
unsigned int last, padn;
unsigned int high, low;
unsigned char msglen[8];
TRACE( MD5_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n");
high = ( poAMPSMD5Context->punTotal[0] >> 29 )
| ( poAMPSMD5Context->punTotal[1] << 3 );
low = ( poAMPSMD5Context->punTotal[0] << 3 );
PUT_UINT32( low, msglen, 0 );
PUT_UINT32( high, msglen, 4 );
last = poAMPSMD5Context->punTotal[0] & 0x3F;
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
AMD5_Update(r_pvAMPSContext, poAMPSMD5Context, md5_padding, padn );
AMD5_Update(r_pvAMPSContext, poAMPSMD5Context, msglen, 8 );
PUT_UINT32( poAMPSMD5Context->punState[0], r_puchMD5Hash, 0 );
PUT_UINT32( poAMPSMD5Context->punState[1], r_puchMD5Hash, 4 );
PUT_UINT32( poAMPSMD5Context->punState[2], r_puchMD5Hash, 8 );
PUT_UINT32( poAMPSMD5Context->punState[3], r_puchMD5Hash, 12 );
TRACE( MD5_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving.\n");
return AMPS_SUCCESS;
}
因篇幅问题不能全部显示,请点此查看更多更全内容