这个md5干嘛用的,大家比我清楚就不说了,这里不是讲md5的原理。要讲md5的原理,网上一大堆,我也不是什么算法很厉害的人,我只是算法搬运工。咱是一般程序员,有时候能完成业务需要就可以,那些伟大算法的发明留个那些伟大的数学家,在此致敬!!!

又是可恶的150字....................................................................................................................凑字分界线

废话不多上码:

#include "md5.hpp"

int main()
{
MD5 md5("12fdsfsdfsdfds");
cout << md5.toString() << endl; // 16字节md5码的16进制表示字符串,方便人阅读
cout << md5.get() << endl; // 16字节点的md5码,输出基本都是乱码
return ;
}

类的源码两个文件:

//md5.hpp

#ifndef __MD5_HPP__
#define __MD5_HPP__ #include <string>
#include "md5_helper.hpp" /* MD5 context. */
typedef struct _MD5_CTX{ /* state (ABCD) */
/*四个32bits数,用于存放最终计算得到的消息摘要。当消息长度〉512bits时,也用于存放每个512bits的中间结果*/
uint32 state[]; /* number of bits, modulo 2^64 (lsb first) */
/*存储原始信息的bits数长度,不包括填充的bits,最长为 2^64 bits,因为2^64是一个64位数的最大值*/
uint32 count[]; /* input buffer */
/*存放输入的信息的缓冲区,512bits*/
uint8 buffer[]; } MD5_CTX; class MD5
{
public:
MD5(); MD5(int8* input); MD5(const MD5& md5); bool operator == (const MD5& md5); MD5& operator = (const MD5& md5); std::string toString(); const uint8* get()const; protected: void encrypt(uint8* input); // 初始化
void _init(); void _update(uint8* input,uint8 inputLen); void _final();
private: MD5_CTX m_ctx; uint8 m_digest[];
}; MD5::MD5()
{
R_memset((uint8*)m_digest,,sizeof(m_digest));
m_digest[]='\0';
} MD5::MD5(int8* input)
{
encrypt((uint8*)input);
} MD5::MD5(const MD5& md5)
{
*this=md5;
} bool MD5::operator==(const MD5& md5)
{
return (R_memcmp(m_digest,md5.m_digest,sizeof(m_digest))==);
} MD5& MD5::operator=(const MD5& md5)
{
R_memcpy(m_digest,md5.m_digest,sizeof(m_digest));
return *this;
} std::string MD5::toString()
{
std::string str;
for (int i=; i<(sizeof(m_digest)/sizeof(int8))-; ++i)
{
int f = m_digest[i] / ;
int s = m_digest[i] % ;
str.push_back((f>= && f<=) ? f+ : (f-)+);
str.push_back((s>= && s<=) ? s+ : (s-)+);
}
return str;
} const uint8* MD5::get()const
{
return m_digest;
} void MD5::encrypt(uint8* input)
{
R_memset((uint8*)m_digest,,sizeof(m_digest));
m_digest[]='\0'; _init(); _update(input,R_strlen((char*)input)); _final();
} void MD5::_init()
{
/*将当前的有效信息的长度设成0,这个很简单,还没有有效信息,长度当然是0了*/
m_ctx.count[] = m_ctx.count[] = ; /* Load magic initialization constants.*/
/*初始化链接变量,算法要求这样,这个没法解释了*/
m_ctx.state[] = 0x67452301;
m_ctx.state[] = 0xefcdab89;
m_ctx.state[] = 0x98badcfe;
m_ctx.state[] = 0x10325476;
} void MD5::_update(uint8* input,uint8 inputLen)
{
unsigned int i, index, partLen; /* Compute number of bytes mod 64 */
/*计算已有信息的bits长度的字节数的模64, 64bytes=512bits。
用于判断已有信息加上当前传过来的信息的总长度能不能达到512bits,
如果能够达到则对凑够的512bits进行一次处理*/
index = (unsigned int)((m_ctx.count[] >> ) & 0x3F); /* Update number of bits *//*更新已有信息的bits长度*/
if((m_ctx.count[] += ((uint32)inputLen << )) < ((uint32)inputLen << ))
m_ctx.count[]++;
m_ctx.count[] += ((uint32)inputLen >> ); /*计算已有的字节数长度还差多少字节可以 凑成64的整倍数*/
partLen = - index; /* Transform as many times as possible.
*/
/*如果当前输入的字节数 大于 已有字节数长度补足64字节整倍数所差的字节数*/
if(inputLen >= partLen)
{
/*用当前输入的内容把context->buffer的内容补足512bits*/
R_memcpy((POINTER)&m_ctx.buffer[index], (POINTER)input, partLen);
/*用基本函数对填充满的512bits(已经保存到context->buffer中) 做一次转换,转换结果保存到context->state中*/
MD5Helper::MD5Transform(m_ctx.state,m_ctx.buffer);
/*
对当前输入的剩余字节做转换(如果剩余的字节<在输入的input缓冲区中>大于512bits的话 ),
转换结果保存到context->state中
*/
for(i = partLen; i + < inputLen; i += )/*把i+63<inputlen改为i+64<=inputlen更容易理解*/
MD5Helper::MD5Transform(m_ctx.state, &input[i]); index = ;
}
else
i = ; /* Buffer remaining input */
/*将输入缓冲区中的不足填充满512bits的剩余内容填充到context->buffer中,留待以后再作处理*/
R_memcpy((POINTER)&m_ctx.buffer[index], (POINTER)&input[i], inputLen-i);
} void MD5::_final()
{
uint8 bits[];
uint32 index, padLen; /* Save number of bits */
/*将要被转换的信息(所有的)的bits长度拷贝到bits中*/
MD5Helper::Encode(bits,m_ctx.count,); /* Pad out to 56 mod 64. */
/* 计算所有的bits长度的字节数的模64, 64bytes=512bits*/
index = (uint32)((m_ctx.count[] >> ) & 0x3f); /*计算需要填充的字节数,padLen的取值范围在1-64之间*/
padLen = (index < ) ? ( - index) : ( - index); /*这一次函数调用绝对不会再导致MD5Transform的被调用,因为这一次不会填满512bits*/
_update(MD5Helper::PADDING,padLen); /* Append length (before padding) */
/*补上原始信息的bits长度(bits长度固定的用64bits表示),这一次能够恰巧凑够512bits,不会多也不会少*/
_update(bits, ); /* Store state in digest */
/*将最终的结果保存到digest中。ok,终于大功告成了*/
MD5Helper::Encode(m_digest, m_ctx.state,); /* Zeroize sensitive information. */
R_memset((void*)(&m_ctx), , sizeof(MD5_CTX));
} #endif
//md5_helper.hpp

/**************************
@brief md5的辅助文件
/**************************/
#ifndef __MD5_HELPER_HPP__
#define __MD5_HELPER_HPP__ #include <stdint.h> // for data type typedef unsigned char uint8; // 8位数据类型
typedef uint32_t uint32;
typedef uint8* POINTER;
typedef char int8; #define R_memset(x, y, z) memset(x, y, z)
#define R_memcpy(x, y, z) memcpy(x, y, z)
#define R_memcmp(x, y, z) memcmp(x, y, z)
#define R_strlen(s) strlen(s)
/* Constants for MD5Transform routine. */
/*md5转换用到的常量,算法本身规定的*/
#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21 /*
接下来的这几个宏定义是md5算法规定的,就是对信息进行md5加密都要做的运算。
据说有经验的高手跟踪程序时根据这几个特殊的操作就可以断定是不是用的md5
*/
/* F, G, H and I are basic MD5 functions.
*/
#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))) /* ROTATE_LEFT rotates x left n bits.
*/
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
Rotation is separate from addition to prevent recomputation.
*/
#define FF(a, b, c, d, x, s, ac) { \
(a) += F ((b), (c), (d)) + (x) + (uint32)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
} #define GG(a, b, c, d, x, s, ac) { \
(a) += G ((b), (c), (d)) + (x) + (uint32)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
} #define HH(a, b, c, d, x, s, ac) { \
(a) += H ((b), (c), (d)) + (x) + (uint32)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
} #define II(a, b, c, d, x, s, ac) { \
(a) += I ((b), (c), (d)) + (x) + (uint32)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
} class MD5Helper
{
public: static void MD5Transform(uint32 [], uint8 []); static void Encode(uint8*,uint32 *,uint32); static void Decode(uint32*,uint8 *,uint8); static uint8 PADDING[];
}; uint8 MD5Helper::PADDING[] = {
0x80, , , , , , , , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , , , ,
}; void MD5Helper::MD5Transform(uint32 state[], uint8 block[])
{
uint32 a = state[], b = state[], c = state[], d = state[], x[]; Decode(x, block, ); /* Round 1 */
FF(a, b, c, d, x[ ], S11, 0xd76aa478); /* 1 */
FF(d, a, b, c, x[ ], S12, 0xe8c7b756); /* 2 */
FF(c, d, a, b, x[ ], S13, 0x242070db); /* 3 */
FF(b, c, d, a, x[ ], S14, 0xc1bdceee); /* 4 */
FF(a, b, c, d, x[ ], S11, 0xf57c0faf); /* 5 */
FF(d, a, b, c, x[ ], S12, 0x4787c62a); /* 6 */
FF(c, d, a, b, x[ ], S13, 0xa8304613); /* 7 */
FF(b, c, d, a, x[ ], S14, 0xfd469501); /* 8 */
FF(a, b, c, d, x[ ], S11, 0x698098d8); /* 9 */
FF(d, a, b, c, x[ ], S12, 0x8b44f7af); /* 10 */
FF(c, d, a, b, x[], S13, 0xffff5bb1); /* 11 */
FF(b, c, d, a, x[], S14, 0x895cd7be); /* 12 */
FF(a, b, c, d, x[], S11, 0x6b901122); /* 13 */
FF(d, a, b, c, x[], S12, 0xfd987193); /* 14 */
FF(c, d, a, b, x[], S13, 0xa679438e); /* 15 */
FF(b, c, d, a, x[], S14, 0x49b40821); /* 16 */ /* Round 2 */
GG(a, b, c, d, x[ ], S21, 0xf61e2562); /* 17 */
GG(d, a, b, c, x[ ], S22, 0xc040b340); /* 18 */
GG(c, d, a, b, x[], S23, 0x265e5a51); /* 19 */
GG(b, c, d, a, x[ ], S24, 0xe9b6c7aa); /* 20 */
GG(a, b, c, d, x[ ], S21, 0xd62f105d); /* 21 */
GG(d, a, b, c, x[], S22, 0x2441453); /* 22 */
GG(c, d, a, b, x[], S23, 0xd8a1e681); /* 23 */
GG(b, c, d, a, x[ ], S24, 0xe7d3fbc8); /* 24 */
GG(a, b, c, d, x[ ], S21, 0x21e1cde6); /* 25 */
GG(d, a, b, c, x[], S22, 0xc33707d6); /* 26 */
GG(c, d, a, b, x[ ], S23, 0xf4d50d87); /* 27 */
GG(b, c, d, a, x[ ], S24, 0x455a14ed); /* 28 */
GG(a, b, c, d, x[], S21, 0xa9e3e905); /* 29 */
GG(d, a, b, c, x[ ], S22, 0xfcefa3f8); /* 30 */
GG(c, d, a, b, x[ ], S23, 0x676f02d9); /* 31 */
GG(b, c, d, a, x[], S24, 0x8d2a4c8a); /* 32 */ /* Round 3 */
HH(a, b, c, d, x[ ], S31, 0xfffa3942); /* 33 */
HH(d, a, b, c, x[ ], S32, 0x8771f681); /* 34 */
HH(c, d, a, b, x[], S33, 0x6d9d6122); /* 35 */
HH(b, c, d, a, x[], S34, 0xfde5380c); /* 36 */
HH(a, b, c, d, x[ ], S31, 0xa4beea44); /* 37 */
HH(d, a, b, c, x[ ], S32, 0x4bdecfa9); /* 38 */
HH(c, d, a, b, x[ ], S33, 0xf6bb4b60); /* 39 */
HH(b, c, d, a, x[], S34, 0xbebfbc70); /* 40 */
HH(a, b, c, d, x[], S31, 0x289b7ec6); /* 41 */
HH(d, a, b, c, x[ ], S32, 0xeaa127fa); /* 42 */
HH(c, d, a, b, x[ ], S33, 0xd4ef3085); /* 43 */
HH(b, c, d, a, x[ ], S34, 0x4881d05); /* 44 */
HH(a, b, c, d, x[ ], S31, 0xd9d4d039); /* 45 */
HH(d, a, b, c, x[], S32, 0xe6db99e5); /* 46 */
HH(c, d, a, b, x[], S33, 0x1fa27cf8); /* 47 */
HH(b, c, d, a, x[ ], S34, 0xc4ac5665); /* 48 */ /* Round 4 */
II(a, b, c, d, x[ ], S41, 0xf4292244); /* 49 */
II(d, a, b, c, x[ ], S42, 0x432aff97); /* 50 */
II(c, d, a, b, x[], S43, 0xab9423a7); /* 51 */
II(b, c, d, a, x[ ], S44, 0xfc93a039); /* 52 */
II(a, b, c, d, x[], S41, 0x655b59c3); /* 53 */
II(d, a, b, c, x[ ], S42, 0x8f0ccc92); /* 54 */
II(c, d, a, b, x[], S43, 0xffeff47d); /* 55 */
II(b, c, d, a, x[ ], S44, 0x85845dd1); /* 56 */
II(a, b, c, d, x[ ], S41, 0x6fa87e4f); /* 57 */
II(d, a, b, c, x[], S42, 0xfe2ce6e0); /* 58 */
II(c, d, a, b, x[ ], S43, 0xa3014314); /* 59 */
II(b, c, d, a, x[], S44, 0x4e0811a1); /* 60 */
II(a, b, c, d, x[ ], S41, 0xf7537e82); /* 61 */
II(d, a, b, c, x[], S42, 0xbd3af235); /* 62 */
II(c, d, a, b, x[ ], S43, 0x2ad7d2bb); /* 63 */
II(b, c, d, a, x[ ], S44, 0xeb86d391); /* 64 */ state[] += a;
state[] += b;
state[] += c;
state[] += d; /* Zeroize sensitive information. */
R_memset((POINTER)x, , sizeof(x));
} void MD5Helper::Encode(uint8*output,uint32*input,uint32 len)
{
unsigned int i, j; for(i = , j = ; j < len; i++, j += ) {
output[j] = (uint8)(input[i] & 0xff);
output[j+] = (uint8)((input[i] >> ) & 0xff);
output[j+] = (uint8)((input[i] >> ) & 0xff);
output[j+] = (uint8)((input[i] >> ) & 0xff);
}
} void MD5Helper::Decode(uint32*output,uint8*input,uint8 len)
{
unsigned int i, j; for(i = , j = ; j < len; i++, j += )
output[i] = ((uint32)input[j]) | (((uint32)input[j+]) << ) |
(((uint32)input[j+]) << ) | (((uint32)input[j+]) << );
} #endif

分享一个md5类的更多相关文章

  1. 分享一个SqliteHelper类

    分享一个SqliteHelper类 SQLite作为一个本地文件数据库相当好用,小巧.快速.支持事务.关系型,甚至可以运行在Android上.在很久以前的一个项目中,我们用过它来将接收到的数据做本地统 ...

  2. 分享一个MD5加密工具类

    来自:http://blog.csdn.net/zranye/article/details/8234480 Es:http://blog.csdn.net/longxibendi/article/d ...

  3. 分享一个手机端好用的jquery ajax分页类

    分享一个手机端好用的jquery ajax分页类 jquery-ias.min.js 1,引入jquery-ias.min.js 2,调用ajax分页 <script type="te ...

  4. 分享一个Snackbar工具类 SnackbarUtils;

    分享一个Snackbar工具类,源代码也是在Github上面找的,自己做了一下修改: 功能如下: 1:设置Snackbar显示时间长短                 1.1:Snackbar.LEN ...

  5. 分享一个自定义的 console 类,让你不再纠结JS中的调试代码的兼容

    问题的产生 在写JS的过程中,为了调试我们常常会写很多 console.log.console.info.console.group.console.warn.console.error代码来查看JS ...

  6. .Net Excel 导出图表Demo(柱状图,多标签页) .net工具类 分享一个简单的随机分红包的实现方式

    .Net Excel 导出图表Demo(柱状图,多标签页) 1 使用插件名称Epplus,多个Sheet页数据应用,Demo为柱状图(Epplus支持多种图表) 2 Epplus 的安装和引用 新建一 ...

  7. 分享一个简单的C#的通用DbHelper类(支持数据连接池)

    每次新项目的时候,都要从头去找一遍数据库工具类.这里分享一个简单实用的C#的通用DbHelper工具类,支持数据连接池. 连接池配置 <connectionStrings> <add ...

  8. 分享一个的c++写的,模仿awk的框架类CAwkDoc

    这是我好多年前,模仿awk写的. awk大家都比较熟悉,使用awk处理文件,读取文件,分割字段这些工作awk自己帮你实现了. 程序员只要编写业务逻辑代码,并且awk还提供了很多常用的字符串操作函数,可 ...

  9. 分享一个动态生成RDLC报表的类

    在实际工作中,当需要进行大批量查询和生成报表的时候,可以使用我写的类. 特点: 无需报表设计器.无需为报表设置数据集 只需要传入查询结果就可以全自动生成报表,传入的对象为Dynamic(目前支持Dat ...

随机推荐

  1. TWinControl的DoubleBuffered属性的作用与举例

    留个爪,网上搜一篇,仔细分析一下.

  2. Linux配置支持高并发TCP连接(socket最大连接数)

    Linux配置支持高并发TCP连接(socket最大连接数) Linux配置支持高并发TCP连接(socket最大连接数)及优化内核参数 2011-08-09 15:20:58|  分类:LNMP&a ...

  3. 嵌入式ARM-Linux开发工具下载地址合集

    insight gdb  http://ftp.twaren.net/Unix/Sourceware/ 说明:GDB可视化调试工具 http://gro.clinux.org/frs/?group_i ...

  4. HDOJ(HDU) 2309 ICPC Score Totalizer Software(求平均值)

    Problem Description The International Clown and Pierrot Competition (ICPC), is one of the most disti ...

  5. 高效算法——C 分饼

    My birthday is coming up and traditionally I’m serving pie. Not just one pie, no, I have a number N ...

  6. Vagrant虚拟机的配置管理

    Vagrant虚拟机的配置管理 一.shell配置管理 二.使用Puppet进行配置管理 三.案例 Apache服务器的自动配置 3.1 shell配置管理 3.2 puppet配置管理 ps:由于最 ...

  7. python 解析xml 文件: Element Tree 方式

    环境 python:3.4.4 准备xml文件 首先新建一个xml文件,countries.xml.内容是在python官网上看到的. <?xml version="1.0" ...

  8. linux 编译安装apache

    1.下载apache.安装apache #wget http://apache.etoak.com//httpd/httpd-2.4.4.tar.gz #tar zxvf httpd-2.4..4.t ...

  9. C - How Many Tables - HDU-1213

    某个人举办生日宴会邀请了很多人来参加,不过呢,这些人有个毛病他们只会与熟悉人的坐在一起,当然他们也信奉朋友的朋友也是朋友这一法则,所以问最少需要多少张桌子...... 好吧我承认这才是裸并查集.... ...

  10. hdoj 1711 Number Sequence【求字串在母串中第一次出现的位置】

    Number Sequence Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...