C语言 MD5的源码实例详解

 更新时间:2017年01月16日 09:38:57   投稿:lqh  
这篇文章主要介绍了C语言 MD5的源码实例详解的相关资料,需要的朋友可以参考下

C语言 MD5源码

md5c.h:

/* POINTER defines a generic pointer type */ 
typedef unsigned char * POINTER; 
 
/* UINT2 defines a two byte word */ 
//typedef unsigned short int UINT2; 
 
/* UINT4 defines a four byte word */ 
typedef unsigned long int UINT4; 
 
 
/* MD5 context. */ 
typedef struct { 
 UINT4 state[4];         /* state (ABCD) */ 
 UINT4 count[2];  /* number of bits, modulo 2^64 (lsb first) */ 
 unsigned char buffer[64];       /* input buffer */ 
} MD5_CTX; 
 
void MD5Init (MD5_CTX *context); 
void MD5Update (MD5_CTX *context, unsigned char *input, unsigned int inputLen); 
void MD5UpdaterString(MD5_CTX *context,const char *string); 
int MD5FileUpdateFile (MD5_CTX *context,char *filename); 
void MD5Final (unsigned char digest[16], MD5_CTX *context); 
void MDString (char *string,unsigned char digest[16]); 
int MD5File (char *filename,unsigned char digest[16]); 

md5c.c:

/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm 
 */ 
 
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All 
rights reserved. 
 
License to copy and use this software is granted provided that it 
is identified as the "RSA Data Security, Inc. MD5 Message-Digest 
Algorithm" in all material mentioning or referencing this software 
or this function. 
 
License is also granted to make and use derivative works provided 
that such works are identified as "derived from the RSA Data 
Security, Inc. MD5 Message-Digest Algorithm" in all material 
mentioning or referencing the derived work. 
 
RSA Data Security, Inc. makes no representations concerning either 
the merchantability of this software or the suitability of this 
software for any particular purpose. It is provided "as is" 
without express or implied warranty of any kind. 
 
These notices must be retained in any copies of any part of this 
documentation and/or software. 
 */ 
#include "md5c.h" 
#include <string.h> 
#include <stdio.h> 
 
/* Constants for MD5Transform routine. 
*/ 
 
 
#define S11 7 
#define S12 12 
#define S13 17 
#define S14 22 
#define S21 5 
#define S22 9 
#define S23 14 
#define S24 20 
#define S31 4 
#define S32 11 
#define S33 16 
#define S34 23 
#define S41 6 
#define S42 10 
#define S43 15 
#define S44 21 
 
static void MD5_memcpy (POINTER output, POINTER input, unsigned int len); 
static void MD5Transform (UINT4 state[4], unsigned char block[64]); 
static void Encode (unsigned char *output, UINT4 *input, unsigned int len); 
static void MD5_memset (POINTER output, int value, unsigned int len); 
static void Decode (UINT4 *output, unsigned char *input, unsigned int len); 
 
static unsigned char PADDING[64] = { 
 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 
}; 
 
/* F, G, H and I are basic MD5 functions. 
*/ 
#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) 
#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) 
#define H(x, y, z) ((x) ^ (y) ^ (z)) 
#define I(x, y, z) ((y) ^ ((x) | (~z))) 
 
/* ROTATE_LEFT rotates x left n bits. 
*/ 
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) 
 
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. 
Rotation is separate from addition to prevent recomputation. 
*/ 
#define FF(a, b, c, d, x, s, ac) { \ 
 (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ 
 (a) = ROTATE_LEFT ((a), (s)); \ 
 (a) += (b); \ 
 } 
#define GG(a, b, c, d, x, s, ac) { \ 
 (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ 
 (a) = ROTATE_LEFT ((a), (s)); \ 
 (a) += (b); \ 
 } 
#define HH(a, b, c, d, x, s, ac) { \ 
 (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ 
 (a) = ROTATE_LEFT ((a), (s)); \ 
 (a) += (b); \ 
 } 
#define II(a, b, c, d, x, s, ac) { \ 
 (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ 
 (a) = ROTATE_LEFT ((a), (s)); \ 
 (a) += (b); \ 
 } 
 
/* MD5 initialization. Begins an MD5 operation, writing a new context. 
 */ 
void MD5Init (MD5_CTX *context)          /* context */ 
{ 
 context->count[0] = context->count[1] = 0; 
 /* Load magic initialization constants. 
 */ 
 context->state[0] = 0x67452301; 
 context->state[1] = 0xefcdab89; 
 context->state[2] = 0x98badcfe; 
 context->state[3] = 0x10325476; 
} 
 
/* MD5 block update operation. Continues an MD5 message-digest 
 operation, processing another message block, and updating the 
 context. 
 */ 
void MD5Update (MD5_CTX *context, unsigned char *input, unsigned int inputLen) 
 
{ 
 unsigned int i, index, partLen; 
 
 /* Compute number of bytes mod 64 */ 
 index = (unsigned int)((context->count[0] >> 3) & 0x3F); 
 
 /* Update number of bits */ 
 if ((context->count[0] += ((UINT4)inputLen << 3)) 
  < ((UINT4)inputLen << 3)) 
  context->count[1]++; 
 context->count[1] += ((UINT4)inputLen >> 29); 
 
 partLen = 64 - index; 
 
 /* Transform as many times as possible. 
 */ 
 if (inputLen >= partLen) { 
  MD5_memcpy((POINTER)&context->buffer[index], (POINTER)input, partLen); 
  MD5Transform (context->state, context->buffer); 
 
  for (i = partLen; i + 63 < inputLen; i += 64) 
   MD5Transform (context->state, &input[i]); 
 
  index = 0; 
 } 
 else 
  i = 0; 
 
 /* Buffer remaining input */ 
 MD5_memcpy((POINTER)&context->buffer[index], (POINTER)&input[i],inputLen-i); 
} 
 
/* MD5 finalization. Ends an MD5 message-digest operation, writing the 
 the message digest and zeroizing the context. 
 */ 
void MD5Final (unsigned char digest[16], MD5_CTX *context)         
{ 
 unsigned char bits[8]; 
 unsigned int index, padLen; 
 
 /* Save number of bits */ 
 Encode (bits, context->count, 8); 
 
 /* Pad out to 56 mod 64. 
 */ 
 index = (unsigned int)((context->count[0] >> 3) & 0x3f); 
 padLen = (index < 56) ? (56 - index) : (120 - index); 
 MD5Update (context, PADDING, padLen); 
 
 /* Append length (before padding) */ 
 MD5Update (context, bits, 8); 
 
 /* Store state in digest */ 
 Encode (digest, context->state, 16); 
 
 /* Zeroize sensitive information. 
 */ 
 MD5_memset ((POINTER)context, 0, sizeof (*context)); 
} 
 
/* MD5 basic transformation. Transforms state based on block. 
 */ 
static void MD5Transform (UINT4 state[4], unsigned char block[64]) 
{ 
 UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; 
 
 Decode (x, block, 64); 
 
 /* Round 1 */ 
 FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ 
 FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ 
 FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ 
 FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ 
 FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ 
 FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ 
 FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ 
 FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ 
 FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ 
 FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ 
 FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ 
 FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ 
 FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ 
 FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ 
 FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ 
 FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ 
 
 /* Round 2 */ 
 GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ 
 GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ 
 GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ 
 GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ 
 GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ 
 GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ 
 GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ 
 GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ 
 GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ 
 GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ 
 GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ 
 GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ 
 GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ 
 GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ 
 GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ 
 GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ 
 
 /* Round 3 */ 
 HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ 
 HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ 
 HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ 
 HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ 
 HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ 
 HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ 
 HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ 
 HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ 
 HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ 
 HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ 
 HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ 
 HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ 
 HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ 
 HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ 
 HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ 
 HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ 
 
 /* Round 4 */ 
 II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ 
 II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ 
 II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ 
 II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ 
 II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ 
 II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ 
 II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ 
 II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ 
 II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ 
 II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ 
 II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ 
 II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ 
 II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ 
 II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ 
 II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ 
 II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ 
 
 state[0] += a; 
 state[1] += b; 
 state[2] += c; 
 state[3] += d; 
 
 /* Zeroize sensitive information. 
 */ 
 MD5_memset ((POINTER)x, 0, sizeof (x)); 
} 
 
/* Encodes input (UINT4) into output (unsigned char). Assumes len is 
 a multiple of 4. 
 */ 
static void Encode (unsigned char *output, UINT4 *input, unsigned int len) 
{ 
 unsigned int i, j; 
 
 for (i = 0, j = 0; j < len; i++, j += 4) { 
  output[j] = (unsigned char)(input[i] & 0xff); 
  output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); 
  output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); 
  output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); 
 } 
} 
 
/* Decodes input (unsigned char) into output (UINT4). Assumes len is 
 a multiple of 4. 
 */ 
static void Decode (UINT4 *output, unsigned char *input, unsigned int len) 
{ 
 unsigned int i, j; 
 
 for (i = 0, j = 0; j < len; i++, j += 4) 
  output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | 
  (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24); 
} 
 
/* Note: Replace "for loop" with standard memcpy if possible. 
 */ 
 
static void MD5_memcpy (POINTER output, POINTER input, unsigned int len) 
{ 
 unsigned int i; 
 
 for (i = 0; i < len; i++) 
  output[i] = input[i]; 
} 
 
/* Note: Replace "for loop" with standard memset if possible. 
 */ 
static void MD5_memset (POINTER output, int value, unsigned int len) 
{ 
 unsigned int i; 
 
 for (i = 0; i < len; i++) 
  ((char *)output)[i] = (char)value; 
} 
/* Digests a string and prints the result. 
 */ 
void MDString (char *string,unsigned char digest[16]) 
{ 
 MD5_CTX context; 
 unsigned int len = strlen (string); 
 
 MD5Init (&context); 
 MD5Update (&context, (unsigned char *)string, len); 
 MD5Final (digest, &context); 
} 
/* Digests a file and prints the result. 
 */ 
int MD5File (char *filename,unsigned char digest[16]) 
{ 
 FILE *file; 
 MD5_CTX context; 
 int len; 
 unsigned char buffer[1024]; 
 
 if ((file = fopen (filename, "rb")) == NULL) 
  return -1; 
 else { 
  MD5Init (&context); 
  while (len = fread (buffer, 1, 1024, file)) 
   MD5Update (&context, buffer, len); 
  MD5Final (digest, &context); 
 
  fclose (file); 
 } 
 return 0; 
} 
void MD5UpdaterString(MD5_CTX *context,const char *string) 
{ 
 unsigned int len = strlen (string); 
 MD5Update (context, (unsigned char *)string, len); 
} 
int MD5FileUpdateFile (MD5_CTX *context,char *filename) 
{ 
 FILE *file; 
 int len; 
 unsigned char buffer[1024]; 
 
 if ((file = fopen (filename, "rb")) == NULL) 
  return -1; 
 else { 
  while (len = fread (buffer, 1, 1024, file)) 
   MD5Update (context, buffer, len); 
  fclose (file); 
 } 
 return 0; 
} 

用法:

void main(void) 
{ 
  unsigned char digest[16]; //存放结果 
 
  //第一种用法: 
 
  MD5_CTX md5c; 
  MD5Init(&md5c); //初始化 
  MD5UpdaterString(&md5c,"你要测试的字符串"); 
  MD5FileUpdateFile(&md5c,"你要测试的文件路径"); 
  MD5Final(digest,&md5c); 
 
  //第二种用法: 
  MDString("你要测试的字符串",digest); //直接输入字符串并得出结果 
 
 //第三种用法: 
 MD5File("你要测试的文件路径",digest); //直接输入文件路径并得出结果 
} 

相关文章:

C++ MD5源码:https://www.jb51.net/article/103113.htm

C语言 MD5源码:https://www.jb51.net/article/103108.htm

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

相关文章

  • 利用QT设计秒表功能

    利用QT设计秒表功能

    这篇文章主要为大家详细介绍了利用QT设计秒表功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • C和C++的函数调用约定你知道多少

    C和C++的函数调用约定你知道多少

    这篇文章主要为大家详细介绍了C和C++的函数调用约定,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • VsCode搭建C语言运行环境详细过程及终端乱码问题解决方案

    VsCode搭建C语言运行环境详细过程及终端乱码问题解决方案

    这篇文章主要介绍了VsCode搭建C语言运行环境以及终端乱码问题解决,在VsCode中搭建C/C++运行环境需要先安装几个插件,具体插件文中给大家详细介绍,需要的朋友可以参考下
    2022-12-12
  • C++实现数字转换为十六进制字符串的方法

    C++实现数字转换为十六进制字符串的方法

    这篇文章主要介绍了C++实现数字转换为十六进制字符串的方法,涉及C++操作数字与字符串转换的相关技巧,需要的朋友可以参考下
    2015-06-06
  • 基于C语言实现扫雷游戏

    基于C语言实现扫雷游戏

    这篇文章主要为大家详细介绍了基于C语言实现扫雷游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-11-11
  • cmake添加一个库的实现步骤

    cmake添加一个库的实现步骤

    本文主要介绍了cmake添加一个库的实现步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06
  • C/C++读取配置文件的方式小结

    C/C++读取配置文件的方式小结

    这篇文章主要为大家详细介绍了C/C++中读取配置文件的几种常见方式,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-04-04
  • c语言随机数函数示例

    c语言随机数函数示例

    这篇文章主要介绍了c语言随机数函数示例,需要的朋友可以参考下
    2014-04-04
  • C++中this指针理解及作用

    C++中this指针理解及作用

    这篇文章主要介绍了C++中this指针理解及作用,文章通过举例展开相关详细内容,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-05-05
  • C++类型转换详解

    C++类型转换详解

    类型转换有c风格的,当然还有c++风格的。c风格的转换的格式很简单(TYPE)EXPRESSION,但是c风格的类型转换有不少的缺点,有的时候用c风格的转换是不合适的,因为它可以在任意类型之间转换
    2021-10-10

最新评论