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. 编写IoDemo.java的Java应用程序,程序完成的功能是:首先读取text.txt文件内容,再通过键盘输入文件的名称为iodemo.txt,把text.txt的内容存入iodemo.txt

    package zuoye; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundExcep ...

  2. 《PHP开发APP接口》笔记

    PHP开发APP接口 [TOC] 课程地址 imooc PHP开发APP接口 学习要点 APP接口简介 封装通信接口方法 核心技术 APP接口实例 服务器端 -> 数据库|缓存 -> 调用 ...

  3. 一、Android学习第一天——环境搭建(转)

    (转自:http://wenku.baidu.com/view/af39b3164431b90d6c85c72f.html) 一. Android学习第一天——环境搭建 Android 开发环境的搭建 ...

  4. Nagios监控ganglia的指标

    这是nagios与ganglia整合的一部分内容 . 通常我们会把ganglia的监控发送给一个主机,我们可以在这个主机上执行nc localhost 8649 可以获取到所有发往这个主机的信息,以x ...

  5. KVM 介绍(7):使用 libvirt 做 QEMU/KVM 快照和 Nova 实例的快照 (Nova Instances Snapshot Libvirt)

    学习 KVM 的系列文章: (1)介绍和安装 (2)CPU 和 内存虚拟化 (3)I/O QEMU 全虚拟化和准虚拟化(Para-virtulizaiton) (4)I/O PCI/PCIe设备直接分 ...

  6. Android中关于Handler的若干思考

    在之前的博文中,讲过一些和Handler有关的知识,例如: Android 多线程----AsyncTask异步任务详解 Android多线程----异步消息处理机制之Handler详解 今天再把Ha ...

  7. java 22 - 3 多线程的概述以及其它所涉及的东西(看)

    1:要想了解多线程,必须先了解线程,而要想了解线程,必须先了解进程,因为线程是依赖于进程而存在. 2:什么是进程? 通过任务管理器我们就看到了进程的存在. 而通过观察,就可以发现只有运行的程序才会出现 ...

  8. poj2632 Crashing Robots

    Crashing Robots Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9859   Accepted: 4209 D ...

  9. LazyInitializationException: could not initialize proxy no session

    这完全是框架设计者的锅,讲道理  无论是SSH SSM都太重了, Hibernate几乎把SQL完全封装了一遍,简单的一对多关系,如果开启LazyLoad 这样实体类会被代理,直到访问这个多方实体的属 ...

  10. 如何用 CSS 做到完全垂直居中

    本文将教你一个很有用的技巧——如何使用 CSS 做到完全的垂直居中.我们都知道 margin:0 auto; 的样式能让元素水平居中,而 margin: auto; 却不能做到垂直居中……直到现在.但 ...