需要注意的几点:

(1)md5存取的数据长度仅为64位,位于数据的最前端,大于令其自然溢出。

(2)update函数和final函数处理得很繁琐,需要仔细分析。

(3)16位md5码取32位md5码的中间16位。

1、Md5.hpp

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<iostream>
#include<cmath>
typedef struct{
unsigned int count[];
unsigned int state[];
unsigned char buffer[];
}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[]);
void MD5Transform(unsigned int state[], unsigned char block[]);
void MD5Encode(unsigned char *output, unsigned int *input, unsigned int len);
void MD5Decode(unsigned int *output, unsigned char *input, unsigned int len);

2、Md5.cpp

#include "Md5.hpp"
unsigned char PADDING[] = {
0x80, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , };
void MD5Init(MD5_CTX *context){
context->count[]=;
context->count[]=;
context->state[]=0x67452301;//链接变量,注意与大端字节序的区别,内存中是小端字节序
context->state[]=0xEFCDAB89;
context->state[]=0x98BADCFE;
context->state[]=0x10325476;
} void MD5Update(MD5_CTX *context, unsigned char *input, unsigned int inputlen){
unsigned int i=,index=,partlen=;
index=(context->count[]>>)&0x3F;//模64字节的余数,第一次调用为0
partlen=-index;//第一次partlen为64
//预留最前面的64位存放数据长度
context->count[]+=inputlen<<;//文本总的位数,低32位
if(context->count[]<(inputlen<<)) context->count[]++;
context->count[]+=inputlen>>;//先左移3,求出位数,再右移32位,求出左32位 if(inputlen>=partlen){
memcpy(&context->buffer[index], input, partlen);
MD5Transform(context->state, context->buffer);
//512位为1组
for(i=partlen;i+<=inputlen;i+=) MD5Transform(context->state,&input[i]);
index=;
}
else i=;
memcpy(&context->buffer[index], &input[i], inputlen-i);//最后剩下的一部分
} //32位md5
void MD5Final(MD5_CTX *context, unsigned char digest[]){
unsigned int index=,padlen=;
unsigned char bits[];
index=(context->count[]>>)&0x3F;//模64字节的余数
padlen=(index<)?(-index):(-index);//需要填充的长度,注意长度占8字节
MD5Encode(bits,context->count,);
MD5Update(context,PADDING,padlen);
MD5Update(context,bits,);//这里调用时,index=0
MD5Encode(digest,context->state,);
} void MD5Encode(unsigned char *output, unsigned int *input, unsigned int len){
unsigned int i = , j = ;//len是char的长度
while (j<len){
output[j]=input[i] & 0xFF;
output[j+]=(input[i]>>)&0xFF;
output[j+]=(input[i]>>)&0xFF;
output[j+]=(input[i]>>)&0xFF;
i++;
j += ;
}
} void MD5Decode(unsigned int *output, unsigned char *input, unsigned int len){
unsigned int i = , j = ;
while (j < len){
output[i] = (input[j]) |
(input[j + ] << ) |
(input[j + ] << ) |
(input[j + ] << );
i++;
j += ;
}
} void MD5Transform(unsigned int state[], unsigned char block[]){
unsigned int a = state[];
unsigned int b = state[];
unsigned int c = state[];
unsigned int d = state[];
unsigned int x[]; MD5Decode(x, block, );
FF(a, b, c, d, x[], , 0xd76aa478);//32位运算
FF(d, a, b, c, x[], , 0xe8c7b756);
FF(c, d, a, b, x[], , 0x242070db);
FF(b, c, d, a, x[], , 0xc1bdceee);
FF(a, b, c, d, x[], , 0xf57c0faf);
FF(d, a, b, c, x[], , 0x4787c62a);
FF(c, d, a, b, x[], , 0xa8304613);
FF(b, c, d, a, x[], , 0xfd469501);
FF(a, b, c, d, x[], , 0x698098d8);
FF(d, a, b, c, x[], , 0x8b44f7af);
FF(c, d, a, b, x[], , 0xffff5bb1);
FF(b, c, d, a, x[], , 0x895cd7be);
FF(a, b, c, d, x[], , 0x6b901122);
FF(d, a, b, c, x[], , 0xfd987193);
FF(c, d, a, b, x[], , 0xa679438e);
FF(b, c, d, a, x[], , 0x49b40821); GG(a, b, c, d, x[], , 0xf61e2562);
GG(d, a, b, c, x[], , 0xc040b340);
GG(c, d, a, b, x[], , 0x265e5a51);
GG(b, c, d, a, x[], , 0xe9b6c7aa);
GG(a, b, c, d, x[], , 0xd62f105d);
GG(d, a, b, c, x[], , 0x2441453);
GG(c, d, a, b, x[], , 0xd8a1e681);
GG(b, c, d, a, x[], , 0xe7d3fbc8);
GG(a, b, c, d, x[], , 0x21e1cde6);
GG(d, a, b, c, x[], , 0xc33707d6);
GG(c, d, a, b, x[], , 0xf4d50d87);
GG(b, c, d, a, x[], , 0x455a14ed);
GG(a, b, c, d, x[], , 0xa9e3e905);
GG(d, a, b, c, x[], , 0xfcefa3f8);
GG(c, d, a, b, x[], , 0x676f02d9);
GG(b, c, d, a, x[], , 0x8d2a4c8a); HH(a, b, c, d, x[], , 0xfffa3942);
HH(d, a, b, c, x[], , 0x8771f681);
HH(c, d, a, b, x[], , 0x6d9d6122);
HH(b, c, d, a, x[], , 0xfde5380c);
HH(a, b, c, d, x[], , 0xa4beea44);
HH(d, a, b, c, x[], , 0x4bdecfa9);
HH(c, d, a, b, x[], , 0xf6bb4b60);
HH(b, c, d, a, x[], , 0xbebfbc70);
HH(a, b, c, d, x[], , 0x289b7ec6);
HH(d, a, b, c, x[], , 0xeaa127fa);
HH(c, d, a, b, x[], , 0xd4ef3085);
HH(b, c, d, a, x[], , 0x4881d05);
HH(a, b, c, d, x[], , 0xd9d4d039);
HH(d, a, b, c, x[], , 0xe6db99e5);
HH(c, d, a, b, x[], , 0x1fa27cf8);
HH(b, c, d, a, x[], , 0xc4ac5665); II(a, b, c, d, x[], , 0xf4292244);
II(d, a, b, c, x[], , 0x432aff97);
II(c, d, a, b, x[], , 0xab9423a7);
II(b, c, d, a, x[], , 0xfc93a039);
II(a, b, c, d, x[], , 0x655b59c3);
II(d, a, b, c, x[], , 0x8f0ccc92);
II(c, d, a, b, x[], , 0xffeff47d);
II(b, c, d, a, x[], , 0x85845dd1);
II(a, b, c, d, x[], , 0x6fa87e4f);
II(d, a, b, c, x[], , 0xfe2ce6e0);
II(c, d, a, b, x[], , 0xa3014314);
II(b, c, d, a, x[], , 0x4e0811a1);
II(a, b, c, d, x[], , 0xf7537e82);
II(d, a, b, c, x[], , 0xbd3af235);
II(c, d, a, b, x[], , 0x2ad7d2bb);
II(b, c, d, a, x[], , 0xeb86d391);
state[] += a;
state[] += b;
state[] += c;
state[] += d;
}

3、Test.cpp

#include "Md5.hpp"
using namespace std;
int main(){ int i;
unsigned char encrypt[] = "admin";//"admin";//21232f297a57a5a743894a0e4a801fc3
unsigned char decrypt[]; MD5_CTX md5; MD5Init(&md5);
MD5Update(&md5, encrypt, (int)strlen((char *)encrypt));//只是个中间步骤
MD5Final(&md5, decrypt);//32位 printf("加密前:%s\n加密后16位:",encrypt);
for (i = ; i<; i++){
printf("%02x", decrypt[i]);
} printf("\n加密前:%s\n加密后32位:",encrypt);
for (i = ; i<; i++){
printf("%02x", decrypt[i]);
} return ;
}

MD5算法的c++实现的更多相关文章

  1. md5算法

    md5算法 不可逆的:原文-->密文.用系统的API可以实现: 123456 ---密文 1987 ----密文: 算法步骤: 1.用每个byte去和11111111做与运算并且得到的是int类 ...

  2. MD5算法 简介

    MD5(单向散列算法)的全称是Message-Digest Algorithm 5(信息-摘要算法),经MD2.MD3和MD4发展而来.MD5算法的使用不需要支付任何版权费用. MD5功能 l 输入任 ...

  3. md5算法原理一窥(其一)

    首先,需要了解的事,md5并不是传说中的加密算法,只是一种散列算法.其加密的算法并不是我们说所的那样固定不变,只是一种映射的关系. 所以解密MD5没有现成的算法,只能用穷举法,把可能出现的明文,用MD ...

  4. Java利用MessageDigest提供的MD5算法加密字符串或文件

    MD5是常用的加密算法,也经常用于校验信息完整,如文件的完整性.用术语讲,MD5是一种消息摘要算法(Message Digest Algorithm).另外还有一种常用的消息摘要算法SHA1.如果想了 ...

  5. python学习笔记(MD5算法)

    博主最近进度停滞了 对web开发理解欠缺好多内容 今天整理下MD5算法,这个涉及到mysql数据库存储用户表密码字段的时候 一般是带有加密的 # -*- coding: utf-8 -*- impor ...

  6. 在MAC平台下编译Ngnix ,由于MD5算法不能编译通过 解决办法

    近期想学习Ngnix 代码,前些日子,对”自己下手狠一次“, 买了MAC 本. 所以想在Mac 上编译,是必须的,不然对不起自己的内心. 不巧遇到了MD5算法编译的问题 src/core/ngx_cr ...

  7. MD5算法步骤详解

    转自MD5算法步骤详解 之前要写一个MD5程序,但是从网络上看到的资料基本上一样,只是讲了一个大概.经过我自己的实践,我决定写一个心得,给需要实现MD5,但又不要求很高深的编程知识的童鞋参考.不多说了 ...

  8. Java 实现Md5算法

    package other; import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;/* * ...

  9. MD5算法【计算文件和字符串的MD5值】

    1. MD5算法是一种散列(hash)算法(摘要算法,指纹算法),不是一种加密算法(易错).任何长度的任意内容都可以用MD5计算出散列值.MD5的前身:MD2.MD3.MD4.介绍工具:CalcMD5 ...

  10. 经常使用MD5算法代码

    经常使用的MD5算法代码日期: 2014年8月4日作者: 铁锚 MD5,全称为 Message Digest Algorithm 5(消息摘要算法第五版).详情请參考 维基百科:MD5  MD5加密后 ...

随机推荐

  1. LeetCode:有效三角形的个数【611】

    LeetCode:有效三角形的个数[611] 题目描述 给定一个包含非负整数的数组,你的任务是统计其中可以组成三角形三条边的三元组个数. 示例 1: 输入: [2,2,3,4] 输出: 3 解释: 有 ...

  2. Scala window下安装

    第一步:Java 设置 检测方法前文已说明,这里不再描述. 如果还为安装,可以参考我们的Java 开发环境配置. 接下来,我们可以从 Scala 官网地址 http://www.scala-lang. ...

  3. 面向对象分析与设计(C++)课堂笔记

    第一次课: 对象是程序设计最基本的单元 对象:对象标识.属性.操作(对象标识又分为内部标识.外部标识) 三三制原则 继承:英文语义”is a kind of” 自动的拥有或隐含的复制 虚基类:解决多继 ...

  4. python学习笔记20160413

    1. type(val) #查看val的类型. 2. 出现错误的时候, 读懂错误信息.3. raw_input('xxx') #读取用户输入都是string类型数据.4. ValueError: in ...

  5. [算法]数组的partition调整

    题目一: 给定一个有序数组arr,调整arr使得这个数组的左半部分没有重复部分且升序,而不用保证右部分是否有序. 例如:arr=[1,2,2,2,3,3,4,5,6,6,7,7,8,8,9,9],调整 ...

  6. poj 3006 Dirichlet's Theorem on Arithmetic Progressions【素数问题】

    题目地址:http://poj.org/problem?id=3006 刷了好多水题,来找回状态...... Dirichlet's Theorem on Arithmetic Progression ...

  7. 算法(Algorithms)第4版 练习 1.4.1

    =N(N-1)(N-2)/6

  8. SQLServer 一些有用的语句

    SET STATISTICS TIME ON 记录查询的相关数据 生成随机Guid SELECT NewID() 按照某一列排序并生成序号 select Row_Number() OVER (ORDE ...

  9. .dhpcd导致cpu飙升问题

    因公司有业务服务器在阿里云上面,阿里云后台报警说,“有恶意程序在挖矿”,引起了高度重视,于是我登陆服务器进行排查. 登陆云服务器:系统centos7.5 第一步使用top查看资源情况. top 可以清 ...

  10. php 二维数组验证一个值是否存在

    php 判断数字在二维数组里 $arr = array( array('a', 'b'), array('c', 'd') ); in_array('a', $arr); // 此时返回的永远都是 f ...