MD5算法的C语言实现
1
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include "md5.h" #ifdef __cplusplus
extern "C" {
#endif #define ROTATELEFT(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) #define TO_HEX_FMT_L "%02x"
#define TO_HEX_FMT_U "%02X" /**
* @desc: convert message and mes_bkp string into integer array and store them in w
*/
static void md5_process_part1(uint32_t *w, const char *message, uint32_t *pos, uint32_t mes_len, const unsigned char *mes_bkp)
{
uint32_t i; // used in for loop for(i = ; i <= ; i++)
{
int32_t count = ;
while(*pos < mes_len && count <= )
{
w[i] += (((uint32_t)message[*pos]) << count);
(*pos)++;
count += ;
}
while(count <= )
{
w[i] += (((uint32_t)mes_bkp[*pos - mes_len]) << count);
(*pos)++;
count += ;
}
}
} /**
* @desc: start encryption based on w
*/
static void md5_process_part2(uint32_t abcd[], uint32_t *w, const uint32_t k[], const uint32_t s[])
{
uint32_t i; // used in for loop uint32_t a = abcd[];
uint32_t b = abcd[];
uint32_t c = abcd[];
uint32_t d = abcd[];
uint32_t f = ;
uint32_t g = ; for(i = ; i < ; i++)
{
if(i >= && i <= )
{
f = (b & c) | ((~b) & d);
g = i;
}else if(i >= && i <= )
{
f = (d & b) | ((~d) & c);
g = ( * i + ) % ;
}else if(i >= && i <= )
{
f = b ^ c ^ d;
g = ( * i + ) % ;
}else if(i >= && i <= )
{
f = c ^ (b | (~d));
g = ( * i) % ;
}
uint32_t temp = d;
d = c;
c = b;
b = ROTATELEFT((a + f + k[i] + w[g]), s[i]) + b;
a = temp;
} abcd[] += a;
abcd[] += b;
abcd[] += c;
abcd[] += d;
} /**
* @desc: format the output, convert numbers to hexdecimal string and store them in result
*/
static void format_output(char *result, size_t size, uint32_t *abcd, uint32_t flag)
{
uint32_t i; // used in for loop memset(result, , size); uint32_t ptr = ;
for(i = ; i < ; i++)
{
ptr += snprintf(result + ptr, size - ptr, (flag == )?TO_HEX_FMT_U:TO_HEX_FMT_L, (abcd[i] & 0x000000FF));
ptr += snprintf(result + ptr, size - ptr, (flag == )?TO_HEX_FMT_U:TO_HEX_FMT_L, (abcd[i] & 0x0000FF00) >> );
ptr += snprintf(result + ptr, size - ptr, (flag == )?TO_HEX_FMT_U:TO_HEX_FMT_L, (abcd[i] & 0x00FF0000) >> );
ptr += snprintf(result + ptr, size - ptr, (flag == )?TO_HEX_FMT_U:TO_HEX_FMT_L, (abcd[i] & 0xFF000000) >> );
}
} /**
* @input: result -- store the calculation result
* size -- size of result. Make sure it's at least 33
* since the result is a 32-byte hexdecimal string.
* message-- string to be encrypted
* flag -- 0 means upper case output, 1 means lower case output
* @return: 0 -- success
* 1 -- result size less than 33
* 2 -- calloc failed
*/
int32_t cal_md5(char *result, size_t size, const char *message, uint32_t flag){
if (result == NULL || size < )
{
return ;
} uint32_t *w = (uint32_t *)calloc(, sizeof(uint32_t));
if(w == NULL)
{
return ;
} uint32_t i; // used in for loop uint32_t mes_len = strlen(message);
uint32_t looptimes = (mes_len + ) / + ;
uint32_t abcd[] = {0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476}; const uint32_t k[]={
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
}; const uint32_t s[]={
,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,
}; uint32_t pos = ; // position pointer for message string
uint32_t bkp_len = * looptimes - mes_len;
unsigned char *bkp_mes = (unsigned char *)calloc(, bkp_len);
if(bkp_mes == NULL)
{
free(w);
return ;
} bkp_mes[] = (unsigned char)(0x80);
uint64_t mes_bit_len = ((uint64_t)mes_len) * ;
for(i = ; i < ; i++)
{
bkp_mes[bkp_len-i-] = (unsigned char)((mes_bit_len & (0x00000000000000FF << ( * ( - i)))) >> ( * ( - i)));
} for(i = ; i < looptimes; i++)
{
memset(w, , * sizeof(uint32_t)); md5_process_part1(w, message, &pos, mes_len, bkp_mes); // compute w md5_process_part2(abcd, w, k, s); // calculate md5 and store the result in abcd
} free(w);
free(bkp_mes); format_output(result, size, abcd, flag); return ;
} #ifdef __cplusplus
}
#endif
2
/**
* @author Horst Xu
* @date 2015-07-10
* @contact 271021733@qq.com
*/
#ifndef __MD5_H__
#define __MD5_H__ #include <stdint.h>
#include <stddef.h> #ifdef __cplusplus
extern "C" {
#endif /**
* @input: result -- store the calculation result
* size -- size of result. Make sure it's at least 33
* since the result is a 32-byte hexdecimal string.
* message-- string to be encrypted
* flag -- 0 means upper case output, 1 means lower case output
* @return: 0 -- success
* 1 -- result size less than 33
* 2 -- calloc failed
*/
int32_t cal_md5(char *result, size_t size, const char *message, uint32_t flag); #ifdef __cplusplus
}
#endif #endif //__MD5_H__
3
#include <stdio.h>
#include <stdint.h>
#include <string.h> #include "md5.h" int32_t main(void)
{
char result[];
int32_t ret = -; //test 1
ret = cal_md5(result, sizeof(result), "abcdegfhijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz123", );
if(ret == && == strncmp(result, "dd2fc541b65e2202d55beae0ecaf6528", strlen(result)))
{
printf("test 1 successful!\n");
}else
{
printf("test 1 failed!\n");
} //test 2
ret = cal_md5(result, sizeof(result), "abcdegfhijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz1234", );
if(ret == && == strncmp(result, "27FF2E8344E7E3F36F9C7E18D0EC82DF", strlen(result)))
{
printf("test 2 successful!\n");
}else
{
printf("test 2 failed!\n");
} //test 3
ret = cal_md5(result, sizeof(result), "abcdegfhijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz12345", );
if(ret == && == strncmp(result, "7A7B1279343946E3A5949BEA1B3BF8AF", strlen(result)))
{
printf("test 3 successful!\n");
}else
{
printf("test 3 failed!\n");
} //test 4
ret = cal_md5(result, sizeof(result), "", );
if(ret == && == strncmp(result, "d41d8cd98f00b204e9800998ecf8427e", strlen(result)))
{
printf("test 4 successful!\n");
}else
{
printf("test 4 failed!\n");
} return ;
}
MD5算法的C语言实现的更多相关文章
- 一个UUID生成算法的C语言实现 --- WIN32版本 .
		
一个UUID生成算法的C语言实现——WIN32版本 cheungmine 2007-9-16 根据定义,UUID(Universally Unique IDentifier,也称GUID)在时 ...
 - 经常使用MD5算法代码
		
经常使用的MD5算法代码日期: 2014年8月4日作者: 铁锚 MD5,全称为 Message Digest Algorithm 5(消息摘要算法第五版).详情请參考 维基百科:MD5 MD5加密后 ...
 - 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 ...
 - 魔方阵算法及C语言实现
		
1 魔方阵概念 填充的,每一行.每一列.对角线之和均相等的方阵,阶数n = 3,4,5….魔方阵也称为幻方阵. 例如三阶魔方阵为: 魔方阵有什么的规律呢? 魔方阵分为奇幻方和偶幻方.而偶幻方又分为是4 ...
 
随机推荐
- 十五天精通WCF——第四天 你一定要明白的通信单元Message
			
转眼你已经学了三天的wcf了,是不是很好奇wcf在传输层上面到底传递的是个什么鸟毛东西呢???应该有人知道是soap,那soap这叼毛长得是什么 样呢?这一篇我们来揭开答案... 一:soap到底长成 ...
 - MySQL 命令行工具之 mysqldump 深入研究
			
mysqldump 是MySQL的一个命令行工具,用于逻辑备份.可以将数据库和表的结构,以及表中的数据分别导出成:create database, create table, insert into的 ...
 - SQL Server 中获取字符串拼音的标量函数实现
			
工作中时常遇到字符串转换为拼音的需求.特别目前在各大网站平台都可以看到的基于拼音的查询功能.如果在查询中增加相应的拼音查询,就可以减少很多的因中文汉字完全输入的不便利,例如:当我要查询叫”郭德 ...
 - DGbroker三种保护模式的切换
			
1.三种保护模式 – Maximum protection 在Maximum protection下, 可以保证从库和主库数据完全一样,做到zero data loss.事务同时在主从两边提交完成,才 ...
 - 关于oracle数据库报12505错误的问题!
			
问题阐述: 导致oracle报12505错误的原因比较多,但是最可能一种原因就是客户端的监听出了问题. 解决办法: 在oracle安装目录下找到listener.ora 和 tnsnames.ora, ...
 - x01.Lab.StoreApp: XP 停服,微软变脸
			
变脸,川剧的一种表演形式,除了哄哄小孩,似乎别无用处.而川剧变脸从业者何其多也,存在时间何其长也.以如此多的从业者,如此长的时间,来进行科研,其成果一定是斐然吧.推而广之,试问天下谁能敌! 微软变脸, ...
 - android 利用线程刷新UI方法
			
新建线程new Thread(new Runnable() 线程方法:public void run() private void setAddWidgetEnabled(boolean enable ...
 - Javascript parseFloat内部解析规则
			
这是由小习发的一个问题引起的讨论,结束后大家各自加深了多parseFloat的理解. 如下 16进制数0x10使用parseFloat转成数字,结果为0.潜意识期望的结果是16. 有人说脑残,16进制 ...
 - 关于Leetcode上二叉树的算法总结
			
二叉树,结构很简单,只是比单链表复杂了那么一丢丢而已.我们先来看看它们结点上的差异: /* 单链表的结构 */ struct SingleList{ int element; struct Singl ...
 - 从vmware下载到Linux环境下jdk和maven的安装
			
写在前面:个人总结,如有不对请指出 操作环境: 操作系统:window7 企业版 处理器:Intel Core i5-4200U CPU @ 1.6GHz 内存:8G 系统类型:64位操作系统 需要安 ...