MD5.h
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<iostream>
#include<cmath>
typedef struct{
unsigned int count[2];
unsigned int state[4];
unsigned char buffer[64];
}MD5_CTX;
#define F(x,y,z) ((x&y)|(~x&z))
#define G(x,y,z) ((x&z)|(y&~z))
#define H(x,y,z) (x^y^z)
#define I(x,y,z) (y^(x|~z))
#define ROTATE_LEFT(x,n) ((x<<n)|(x>>(32-n)))
#define FF(a,b,c,d,x,s,ac) { a+=F(b,c,d)+x+ac; a=ROTATE_LEFT(a,s); a+=b;}
#define GG(a,b,c,d,x,s,ac) { a+=G(b,c,d)+x+ac; a=ROTATE_LEFT(a,s); a+=b;}
#define HH(a,b,c,d,x,s,ac) { a+=H(b,c,d)+x+ac; a=ROTATE_LEFT(a,s); a+=b;}
#define II(a,b,c,d,x,s,ac) { a+=I(b,c,d)+x+ac; a=ROTATE_LEFT(a,s); a+=b;}
void MD5Init(MD5_CTX *context);
void MD5Update(MD5_CTX *context, unsigned char *input, unsigned int inputlen);
void MD5Final(MD5_CTX *context, unsigned char digest[16]);
void MD5Transform(unsigned int state[4], unsigned char block[64]);
void MD5Encode(unsigned char *output, unsigned int *input, unsigned int len);
void MD5Decode(unsigned int *output, unsigned char *input, unsigned int len);
unsigned char PADDING[] = {
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 };
void MD5Init(MD5_CTX *context){
context->count[0]=0;
context->count[1]=0;
context->state[0]=0x67452301;//链接变量,注意与大端字节序的区别,内存中是小端字节序
context->state[1]=0xEFCDAB89;
context->state[2]=0x98BADCFE;
context->state[3]=0x10325476;
}
void MD5Update(MD5_CTX *context, unsigned char *input, unsigned int inputlen){
unsigned int i=0,index=0,partlen=0;
index=(context->count[0]>>3)&0x3F;//模64字节的余数,第一次调用为0
partlen=64-index;//第一次partlen为64
//预留最前面的64位存放数据长度
context->count[0]+=inputlen<<3;//文本总的位数,低32位
if(context->count[0]<(inputlen<<3)) context->count[1]++;
context->count[1]+=inputlen>>29;//先左移3,求出位数,再右移32位,求出左32位
if(inputlen>=partlen){
memcpy(&context->buffer[index], input, partlen);
MD5Transform(context->state, context->buffer);
//512位为1组
for(i=partlen;i+64<=inputlen;i+=64) MD5Transform(context->state,&input[i]);
index=0;
}
else i=0;
memcpy(&context->buffer[index], &input[i], inputlen-i);//最后剩下的一部分
}
//32位md5
void MD5Final(MD5_CTX *context, unsigned char digest[16]){
unsigned int index=0,padlen=0;
unsigned char bits[8];
index=(context->count[0]>>3)&0x3F;//模64字节的余数
padlen=(index<56)?(