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 ...
随机推荐
- Linux服务器文件删除空间未释放的问题
一.问题起源 在Linux系统中,通过rm删除文件将会从文件系统的目录结构上解除链接(unlink),如果文件是被打开的(有一个进程正在使用),那么进程将仍然可以读取该文件磁盘空间也一直被占用 这样就 ...
- DGbroker主备切换
1.检查DG是否正常 DGMGRL> show configuration; Configuration - dgc Protection Mode: MaxProtection Databas ...
- Javascript Function()中的降龙十八掌
原文地址:http://tutorialzine.com/2014/08/what-does-this-function-do/ 下面列出十八个JS function,看你知道这些函数是干嘛用的,你能 ...
- 烂泥:KVM使用NAT联网并为VM配置iptables端口转发
本文由秀依林枫提供友情赞助,首发于烂泥行天下. 在前面的文章中,我们介绍KVM的虚拟机(以下简称VM)都是通过桥接方式进行联网的. 本篇文章我们来介绍KVM的VM通过NAT方式进行联网,并且通过配置I ...
- Android ImageView(scaleType属性)(转)
(转自:http://www.open-open.com/lib/view/open1378257991687.html) <ImageView android:id="@+id/im ...
- [转]CISP(注册信息安全专业人员)认证(12天)
本文转自:http://www.topsec.com.cn/shpx/rzpx/pxkc/cisp/index.htm CISP(注册信息安全专业人员)认证(11天) 中国信息安全产品测评认证中心(C ...
- 150929-拖延高于懒-HTML(End)
四天未更了,分别是因为Xshell和虚拟机链接不好,累,懒(好像是三天..) 就像我一直嗷嗷着要去学开出一样,5年都没有去......拖延症似乎比懒癌更可怕.慢慢的慢慢的,人长大了,小时候的一些东西才 ...
- ITer的七夕节,你的情人在哪里(2015-08-19)
自写<一个程序猿的生命周期>连载以来,迎来第一个七夕节,打算写篇文章纪念一下.我主张过中国自己的节日的,也不反对过其他国家的节日,但是要搞清楚其他国家节日的由来,不要把别人的鬼节当成我们的 ...
- bzoj-2243 2243: [SDOI2011]染色(树链剖分)
题目链接: 2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 6267 Solved: 2291 Descript ...
- Android屏幕禁止休眠的方法
实现这一功能的方法有两种,一种是在Manifest.xml文件里面声明,一种是在代码里面修改LayoutParams的标志位.具体如下: 1.在Manifest.xml文件里面用user-permis ...