md5算法介绍参考wiki: md5 algorithm
#ifndef _DEFINE_MD5_H_
#define _DEFINE_MD5_H_
#ifndef _STRING_H_
#define _STRING_H_
#include <string>
#endif
class MD5{
public:
typedef unsigned int uint32_t;
private:
uint32_t* _msgdgt;
uint32_t* _k;
uint32_t* _s;
public:
MD5();
~MD5();
private:
void reset();
unsigned int* preProcess(std::string data);
void handleBlock(uint32_t* block);
protected:
virtual unsigned int step1(uint32_t b, uint32_t c, uint32_t d);
virtual unsigned int step2(uint32_t b, uint32_t c, uint32_t d);
virtual unsigned int step3(uint32_t b, uint32_t c, uint32_t d);
virtual unsigned int step4(uint32_t b, uint32_t c, uint32_t d);
virtual unsigned int leftRotate(uint32_t value, uint32_t n);
public:
std::string getMD5(std::string data);
};
#endif
#include "md5.h"
MD5::MD5(): _msgdgt(NULL), _k(NULL), _s(NULL){}
MD5::~MD5(){
if(_msgdgt) delete[] _msgdgt;
if(_k) delete[] _k;
if(_s) delete[] _s;
}
void MD5::reset(){
if(_msgdgt == NULL){
_msgdgt = new uint32_t[4];
}
if(_k == NULL){
_k = new uint32_t[64];
}
if(_s == NULL){
_s = new uint32_t[64];
}
_msgdgt[0] = 0x67452301;
_msgdgt[1] = 0xefcdab89;
_msgdgt[2] = 0x98badcfe;
_msgdgt[3] = 0x10325476;
uint32_t k[64] = {
0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
};
for(int i = 0; i < 64; ++i) _k[i] = k[i];
uint32_t s[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) _s[i] = s[i];
}
unsigned int* MD5::preProcess(std::string data){
uint32_t _block_num_ = (data.length() + 8)/64 + 1;
uint32_t* _block_ = new uint32_t[_block_num_*16];
uint32_t i = 0;
for(i = 0; i < _block_num_*16; ++i)
_block_[i] = 0x00000000;
for(i = 0; i < data.length(); ++i){
_block_[i >> 2] |= ((uint32_t)data[i]) << ((i%4) * 8);
}
_block_[i >> 2] |= 0x80 << ((i%4)*8);
_block_[_block_num_*16-2] = data.length()*8;
return _block_;
}
void MD5::handleBlock(uint32_t* block){
uint32_t a, b, c, d, temp = 0x00000000;
a = _msgdgt[0];
b = _msgdgt[1];
c = _msgdgt[2];
d = _msgdgt[3];
for(uint32_t i = 0; i < 64; ++i){
uint32_t f = 0x00000000;
uint32_t g = 0x00000000;
if(i < 16){
f = step1(b, c, d);
g = i%16;
}else if(i < 32){
f = step2(b, c, d);
g = (5*i+1)%16;
}else if(i < 48){
f = step3(b, c, d);
g = (3*i+5)%16;
}else{
f = step4(b, c, d);
g = (7*i)%16;
}
temp = d;
d = c;
c = b;
b = b + leftRotate(a+f+block[g]+_k[i], _s[i]);
a = temp;
}
_msgdgt[0] = (_msgdgt[0] + a) & 0xffffffff;
_msgdgt[1] = (_msgdgt[1] + b) & 0xffffffff;
_msgdgt[2] = (_msgdgt[2] + c) & 0xffffffff;
_msgdgt[3] = (_msgdgt[3] + d) & 0xffffffff;
}
unsigned int MD5::step1(uint32_t b, uint32_t c, uint32_t d){
return (b & c) | ((~b) & d);
}
unsigned int MD5::step2(uint32_t b, uint32_t c, uint32_t d){
return (b & d) | (c & (~d));
}
unsigned int MD5::step3(uint32_t b, uint32_t c, uint32_t d){
return (b ^ c ^ d);
}
unsigned int MD5::step4(uint32_t b, uint32_t c, uint32_t d){
return (c ^ (b | (~d)));
}
unsigned int MD5::leftRotate(uint32_t value, uint32_t n){
return (value << n) | (value >> (32-n));
}
std::string MD5::getMD5(std::string data){
reset();
uint32_t blockNum = (data.length()+8)/64 + 1;
uint32_t* blockGroup = preProcess(data);
uint32_t* block = new uint32_t[16];
for(uint32_t i = 0; i < blockNum; ++i){
for(int j = 0; j < 16; ++j)
block[j] = blockGroup[i*16+j];
handleBlock(block);
}
delete[] block;
delete[] blockGroup;
std::string md5;
char charmap[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
for(int i = 0; i < 4; ++i){
int d1 = (_msgdgt[i] & 0x0000000f);
int d2 = (_msgdgt[i] & 0x000000f0) >> 4;
int d3 = (_msgdgt[i] & 0x00000f00) >> 8;
int d4 = (_msgdgt[i] & 0x0000f000) >> 12;
int d5 = (_msgdgt[i] & 0x000f0000) >> 16;
int d6 = (_msgdgt[i] & 0x00f00000) >> 20;
int d7 = (_msgdgt[i] & 0x0f000000) >> 24;
int d8 = (_msgdgt[i] & 0xf0000000) >> 28;
md5.push_back(charmap[d2]);
md5.push_back(charmap[d1]);
md5.push_back(charmap[d4]);
md5.push_back(charmap[d3]);
md5.push_back(charmap[d6]);
md5.push_back(charmap[d5]);
md5.push_back(charmap[d8]);
md5.push_back(charmap[d7]);
}
return md5;
}
源代码下载地址: md5 algorithm