MD5算法的c++实现
需要注意的几点:
(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++实现的更多相关文章
- md5算法
md5算法 不可逆的:原文-->密文.用系统的API可以实现: 123456 ---密文 1987 ----密文: 算法步骤: 1.用每个byte去和11111111做与运算并且得到的是int类 ...
- MD5算法 简介
MD5(单向散列算法)的全称是Message-Digest Algorithm 5(信息-摘要算法),经MD2.MD3和MD4发展而来.MD5算法的使用不需要支付任何版权费用. MD5功能 l 输入任 ...
- md5算法原理一窥(其一)
首先,需要了解的事,md5并不是传说中的加密算法,只是一种散列算法.其加密的算法并不是我们说所的那样固定不变,只是一种映射的关系. 所以解密MD5没有现成的算法,只能用穷举法,把可能出现的明文,用MD ...
- Java利用MessageDigest提供的MD5算法加密字符串或文件
MD5是常用的加密算法,也经常用于校验信息完整,如文件的完整性.用术语讲,MD5是一种消息摘要算法(Message Digest Algorithm).另外还有一种常用的消息摘要算法SHA1.如果想了 ...
- python学习笔记(MD5算法)
博主最近进度停滞了 对web开发理解欠缺好多内容 今天整理下MD5算法,这个涉及到mysql数据库存储用户表密码字段的时候 一般是带有加密的 # -*- coding: utf-8 -*- impor ...
- 在MAC平台下编译Ngnix ,由于MD5算法不能编译通过 解决办法
近期想学习Ngnix 代码,前些日子,对”自己下手狠一次“, 买了MAC 本. 所以想在Mac 上编译,是必须的,不然对不起自己的内心. 不巧遇到了MD5算法编译的问题 src/core/ngx_cr ...
- MD5算法步骤详解
转自MD5算法步骤详解 之前要写一个MD5程序,但是从网络上看到的资料基本上一样,只是讲了一个大概.经过我自己的实践,我决定写一个心得,给需要实现MD5,但又不要求很高深的编程知识的童鞋参考.不多说了 ...
- Java 实现Md5算法
package other; import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;/* * ...
- MD5算法【计算文件和字符串的MD5值】
1. MD5算法是一种散列(hash)算法(摘要算法,指纹算法),不是一种加密算法(易错).任何长度的任意内容都可以用MD5计算出散列值.MD5的前身:MD2.MD3.MD4.介绍工具:CalcMD5 ...
- 经常使用MD5算法代码
经常使用的MD5算法代码日期: 2014年8月4日作者: 铁锚 MD5,全称为 Message Digest Algorithm 5(消息摘要算法第五版).详情请參考 维基百科:MD5 MD5加密后 ...
随机推荐
- 3django url name详解
打开urls.py from django.conf.urls import url from django.contrib import admin from calc import views a ...
- MySQL与Oracle的语法区别详细对比
MySQL与Oracle的语法区别详细对比 Oracle和mysql的一些简单命令对比在本文中将会涉及到很多的实例,感兴趣的你不妨学习一下,就当巩固自己的知识了 Oracle和mysql的一些简单 ...
- apache中配置php支持模块模式、cgi模式和fastcgi模式的实验
首先安装apache.mysql和php,依次顺序安装. 1.apache.mysql的安装比较简单,略过 2. php的安装,我安装的是php5.3.6内置了php-fpm,所以不需要再单独下补丁了 ...
- Hadoop 运行jar包时 java.lang.ClassNotFoundException: Class com.zhen.mr.RunJob$HotMapper not found
错误如下 Error: java.lang.RuntimeException: java.lang.ClassNotFoundException: Class com.zhen.mr.RunJob$H ...
- 解析XML(3)
SAXReader reader = new SAXReader(); Document doc = reader.read(new FileInputStream("emplist.xml ...
- el表达式判断字符串相等
el表达式判断字符串相等 Java code 1 ${"a" == "a"} ${"b" eq "b"} 都可以 & ...
- HashOperations
存储格式:Key=>(Map<HK,HV>) 1.put(H key, HK hashKey, HV value) putAll(H key, java.util.Map<? ...
- python 正则表达式(二)
下面列举了Python3的所有符号用法,别背,千万别背,用到时来查就行. 字符 含义 . 表示匹配除了换行符外的任何字符注:通过设置 re.DOTALL 标志可以使 . 匹配任何字符(包含换行符) | ...
- cluster KMeans need preprocessing scale????
Out: n_digits: 10, n_samples 1797, n_features 64 ___________________________________________________ ...
- spring MVC--配置注解
<context-param> 作用:该元素用来声明应用范围(整个WEB项目)内的上下文初始化参数 param-name 设定上下文的参数名称.必须是唯一名称 param-value 设定 ...