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 ...
随机推荐
- spring hibernate摘记
一.spring 1.ContextLoaderListener 它作用就是启动Web容器时,自动装配ApplicationContext的配置信息.因为它实现了ServletContextLi ...
- Elasticsearch 安装中文分词
github地址:https://github.com/medcl/elasticsearch-analysis-ik 注意版本要对应,否则编译完成后elasticsearch不能正常启动 下载文件, ...
- ctargs使用
ctargs为源码的变量/对象.结构体/类.函数/接口.宏等产生索引文件,以便快速定位.目前支持41种语言,这里仅以C/C++为例:ctags可以产生c/c++语言所有类型的索引文件,具体如下: -& ...
- android 设置布局横屏竖屏
只要在AndroidManifest.xml里面配置一下就可以了.在AndroidManifest.xml的activity(需要禁止转向的activity)配置中加入android:screenOr ...
- 关于 RTL8723BS 同时开启 STA/AP 模式
最近接到一个调试 wifi 驱动的任务,使用的是 rtl8723bs 芯片组.要求是让无线设备工作在 station 模式的时候同时开启一个 ap 热点.简单来讲就是连接其他 wifi 的同时发出一个 ...
- Linux 下从头再走 GTK+-3.0 (二)
仅仅创建一个空白窗口是不够的,下面我们为创建的窗口添加一个按钮. 以 Hello,World!为例. 首先创建一个源文件:example2.c 内容如下. #include <gtk/gtk.h ...
- 初试MarkDown
· 要写个文档,突然就想到要不要试试学学MarkDown,整理一下大致过程 · 首先搜到这篇文章 ,简单介绍了MarkDown,以及OS X 平台上一个简单的工具 mou (目前仍免费) 相关新闻不做 ...
- 关于JavaScript继承的那些事
在JavaScript中,对象的创建可以脱离类型(class free),通过字面量的方式可以很方便的创建出自定义对象. 另外,JavaScript中拥有原型这个强大的概念,当对象进行属性查找的时候, ...
- Shell命令行操作
1.1 shell提示符 [me@linuxbox ~]$ 如果最后一个字符是"#",表示当前终端会话有超级用户权限.使用root用户登录或者使用能提供超级用户权限的终端能获得该权 ...
- NOIP2000进制转换
题目描述 我们可以用这样的方式来表示一个十进制数: 将每个阿拉伯数字乘以一个以该数字所处位置的(值减1)为指数,以10为底数的幂之和的形式.例如:123可表示为 1*10^2+2*10^1+3*10^ ...