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语言实现的更多相关文章

  1. 一个UUID生成算法的C语言实现 --- WIN32版本 .

    一个UUID生成算法的C语言实现——WIN32版本   cheungmine 2007-9-16   根据定义,UUID(Universally Unique IDentifier,也称GUID)在时 ...

  2. 经常使用MD5算法代码

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

  3. md5算法

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

  4. MD5算法 简介

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

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

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

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

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

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

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

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

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

  9. 魔方阵算法及C语言实现

    1 魔方阵概念 填充的,每一行.每一列.对角线之和均相等的方阵,阶数n = 3,4,5….魔方阵也称为幻方阵. 例如三阶魔方阵为: 魔方阵有什么的规律呢? 魔方阵分为奇幻方和偶幻方.而偶幻方又分为是4 ...

随机推荐

  1. JVM知识点

    先发个链接到两位大牛的主页 http://rednaxelafx.iteye.com/               http://icyfenix.iteye.com/ 目录 1)概述 2)编译 3) ...

  2. my_strcat()

    char* my_strcat(char* S1,const char* S2){ //严格符合strcat()的接口形式,需要的S1空间是两个字符串空间总和-1. int i=0,j=0; whil ...

  3. 浅谈 Linux 内核无线子系统

    浅谈 Linux 内核无线子系统 本文目录 1. 全局概览 2. 模块间接口 3. 数据路径与管理路径 4. 数据包是如何被发送? 5. 谈谈管理路径 6. 数据包又是如何被接收? 7. 总结一下 L ...

  4. PADS_AD_Cadence转换

    PADS_AD_Cadence转换 软件版本:PADS的版本是PADS9.5,Altium designer的版本是Altium designer winter 09 PADS和AD的转换 PADS的 ...

  5. C中的数组与指针问题

    反复在数组名与指针上犯错误,特记录下. ,,,,}; int *p, *q; p = (); q = (); *(p+1)?   *(q-1) ? 答案是 3, 5.这里主要涉及的问题就是指针参与运算 ...

  6. 浏览器默认样式(user agent stylesheet)+cssreset

    每种浏览器都有一套默认的样式表,即user agent stylesheet,在写网页时,没有指定的样式,按浏览器内置的样式表来渲染.这是合理的,像word中也有一些预留样式,可以让我们的排版更美观整 ...

  7. [转]NopCommerce How to code my own payment method

    本文转自:http://docs.nopcommerce.com/display/nc/How+to+code+my+own+payment+method Payment methods are im ...

  8. unix automake 使用,快速生成你的Makefile

    使用automake快速生成编译的Makefile 1,确保自己装有的软件automake autoconf 2, 1)执行autoscan 并将生成的configure.scan重命名为config ...

  9. USB hacker Collection

    This blog contains some ideas and tricks about USB hacking.

  10. 第27章 结构型模式大PK

    27.1 代理模式 VS 装饰模式 27.1.1 代理模式 (1)场景:客人找运动员代理要求安排运动员参加比赛 (2)说明:代理人有控制权,可以拒绝客人的要求,也可以答应安排,甚至自己下去跑(因为有些 ...