参考:

1、http://blog.csdn.net/iaccepted/article/details/8722444

2、http://hi.baidu.com/gh0st_lover/item/9d967bddaccb12252b35c7e4

Makefile:

CC=gcc
CFLAGS=-Wall md:md5.o main.o
$(CC) $^ -o $@
md5.o:md5.c
$(CC) $^ -c -o $@
main.o:main.c
$(CC) $^ -c -o $@ clean:
rm -rf md *.o

main.c

#include <stdio.h>
#include <string.h> #include "md5.h" int main () { char tmp[];
int i;
unsigned char digest[]; MD5_CTX context; printf("亲,请输入想加密的字符串\n"); scanf("%s",tmp); MD5Init (&context); MD5Update (&context, (unsigned char*)tmp, strlen(tmp)); MD5Final (digest,&context); printf("加密结果:"); for(i=; i<; ++i) { printf("%02x",digest[i]); } printf("\n"); return ; }

md5.c

#include <stdio.h>
#include <memory.h>
#include "md5.h" #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 MD5Transform (UINT32 a[], unsigned char b[]);
static void Encode (unsigned char *, UINT32 *, unsigned int);
static void Decode (UINT32 *, unsigned char *, unsigned int); static unsigned char PADDING[] = {
0x80, , , , , , , , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , , , ,
}; #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))) #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) #define FF(a, b, c, d, x, s, ac) { \
(a) += F ((b), (c), (d)) + (x) + (UINT32)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) { \
(a) += G ((b), (c), (d)) + (x) + (UINT32)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define HH(a, b, c, d, x, s, ac) { \
(a) += H ((b), (c), (d)) + (x) + (UINT32)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define II(a, b, c, d, x, s, ac) { \
(a) += I ((b), (c), (d)) + (x) + (UINT32)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
} void MD5Init (MD5_CTX *context)
{
context->count[] = context->count[] = ; context->state[] = 0x67452301;
context->state[] = 0xefcdab89;
context->state[] = 0x98badcfe;
context->state[] = 0x10325476;
} void MD5Update (MD5_CTX *context, unsigned char *input, unsigned int inputLen)
{
unsigned int i, index, partLen; index = (unsigned int)((context->count[] >> ) & 0x3F); if ((context->count[] += ((UINT32)inputLen << ))
< ((UINT32)inputLen << ))
context->count[]++;
context->count[] += ((UINT32)inputLen >> ); partLen = - index; if (inputLen >= partLen) {
memcpy((unsigned char *)&context->buffer[index], (unsigned char *)input, partLen);
MD5Transform (context->state, context->buffer); for (i = partLen; i + < inputLen; i += )
MD5Transform (context->state, &input[i]); index = ;
}
else
i = ; memcpy((unsigned char *)&context->buffer[index], (unsigned char *)&input[i],
inputLen-i);
} void MD5Final (unsigned char digest[], MD5_CTX * context)
{
unsigned char bits[];
unsigned int index, padLen; Encode (bits, context->count, ); index = (unsigned int)((context->count[] >> ) & 0x3f);
padLen = (index < ) ? ( - index) : ( - index);
MD5Update (context, PADDING, padLen); MD5Update (context, bits, ); Encode (digest, context->state, ); memset ((unsigned char *)context, , sizeof (*context));
} static void MD5Transform (UINT32 state[], unsigned char block[])
{
UINT32 a = state[], b = state[], c = state[], d = state[], x[]; Decode (x, block, ); /* Round 1 */
FF (a, b, c, d, x[ ], S11, 0xd76aa478); /* 1 */
FF (d, a, b, c, x[ ], S12, 0xe8c7b756); /* 2 */
FF (c, d, a, b, x[ ], S13, 0x242070db); /* 3 */
FF (b, c, d, a, x[ ], S14, 0xc1bdceee); /* 4 */
FF (a, b, c, d, x[ ], S11, 0xf57c0faf); /* 5 */
FF (d, a, b, c, x[ ], S12, 0x4787c62a); /* 6 */
FF (c, d, a, b, x[ ], S13, 0xa8304613); /* 7 */
FF (b, c, d, a, x[ ], S14, 0xfd469501); /* 8 */
FF (a, b, c, d, x[ ], S11, 0x698098d8); /* 9 */
FF (d, a, b, c, x[ ], S12, 0x8b44f7af); /* 10 */
FF (c, d, a, b, x[], S13, 0xffff5bb1); /* 11 */
FF (b, c, d, a, x[], S14, 0x895cd7be); /* 12 */
FF (a, b, c, d, x[], S11, 0x6b901122); /* 13 */
FF (d, a, b, c, x[], S12, 0xfd987193); /* 14 */
FF (c, d, a, b, x[], S13, 0xa679438e); /* 15 */
FF (b, c, d, a, x[], S14, 0x49b40821); /* 16 */ /* Round 2 */
GG (a, b, c, d, x[ ], S21, 0xf61e2562); /* 17 */
GG (d, a, b, c, x[ ], S22, 0xc040b340); /* 18 */
GG (c, d, a, b, x[], S23, 0x265e5a51); /* 19 */
GG (b, c, d, a, x[ ], S24, 0xe9b6c7aa); /* 20 */
GG (a, b, c, d, x[ ], S21, 0xd62f105d); /* 21 */
GG (d, a, b, c, x[], S22, 0x2441453); /* 22 */
GG (c, d, a, b, x[], S23, 0xd8a1e681); /* 23 */
GG (b, c, d, a, x[ ], S24, 0xe7d3fbc8); /* 24 */
GG (a, b, c, d, x[ ], S21, 0x21e1cde6); /* 25 */
GG (d, a, b, c, x[], S22, 0xc33707d6); /* 26 */
GG (c, d, a, b, x[ ], S23, 0xf4d50d87); /* 27 */
GG (b, c, d, a, x[ ], S24, 0x455a14ed); /* 28 */
GG (a, b, c, d, x[], S21, 0xa9e3e905); /* 29 */
GG (d, a, b, c, x[ ], S22, 0xfcefa3f8); /* 30 */
GG (c, d, a, b, x[ ], S23, 0x676f02d9); /* 31 */
GG (b, c, d, a, x[], S24, 0x8d2a4c8a); /* 32 */ /* Round 3 */
HH (a, b, c, d, x[ ], S31, 0xfffa3942); /* 33 */
HH (d, a, b, c, x[ ], S32, 0x8771f681); /* 34 */
HH (c, d, a, b, x[], S33, 0x6d9d6122); /* 35 */
HH (b, c, d, a, x[], S34, 0xfde5380c); /* 36 */
HH (a, b, c, d, x[ ], S31, 0xa4beea44); /* 37 */
HH (d, a, b, c, x[ ], S32, 0x4bdecfa9); /* 38 */
HH (c, d, a, b, x[ ], S33, 0xf6bb4b60); /* 39 */
HH (b, c, d, a, x[], S34, 0xbebfbc70); /* 40 */
HH (a, b, c, d, x[], S31, 0x289b7ec6); /* 41 */
HH (d, a, b, c, x[ ], S32, 0xeaa127fa); /* 42 */
HH (c, d, a, b, x[ ], S33, 0xd4ef3085); /* 43 */
HH (b, c, d, a, x[ ], S34, 0x4881d05); /* 44 */
HH (a, b, c, d, x[ ], S31, 0xd9d4d039); /* 45 */
HH (d, a, b, c, x[], S32, 0xe6db99e5); /* 46 */
HH (c, d, a, b, x[], S33, 0x1fa27cf8); /* 47 */
HH (b, c, d, a, x[ ], S34, 0xc4ac5665); /* 48 */ /* Round 4 */
II (a, b, c, d, x[ ], S41, 0xf4292244); /* 49 */
II (d, a, b, c, x[ ], S42, 0x432aff97); /* 50 */
II (c, d, a, b, x[], S43, 0xab9423a7); /* 51 */
II (b, c, d, a, x[ ], S44, 0xfc93a039); /* 52 */
II (a, b, c, d, x[], S41, 0x655b59c3); /* 53 */
II (d, a, b, c, x[ ], S42, 0x8f0ccc92); /* 54 */
II (c, d, a, b, x[], S43, 0xffeff47d); /* 55 */
II (b, c, d, a, x[ ], S44, 0x85845dd1); /* 56 */
II (a, b, c, d, x[ ], S41, 0x6fa87e4f); /* 57 */
II (d, a, b, c, x[], S42, 0xfe2ce6e0); /* 58 */
II (c, d, a, b, x[ ], S43, 0xa3014314); /* 59 */
II (b, c, d, a, x[], S44, 0x4e0811a1); /* 60 */
II (a, b, c, d, x[ ], S41, 0xf7537e82); /* 61 */
II (d, a, b, c, x[], S42, 0xbd3af235); /* 62 */
II (c, d, a, b, x[ ], S43, 0x2ad7d2bb); /* 63 */
II (b, c, d, a, x[ ], S44, 0xeb86d391); /* 64 */ state[] += a;
state[] += b;
state[] += c;
state[] += d; memset ((unsigned char *)x, , sizeof (x));
} static void Encode (unsigned char *output, UINT32 *input, unsigned int len)
{
unsigned int i, j; for (i = , j = ; j < len; i++, j += ) {
output[j] = (unsigned char)(input[i] & 0xff);
output[j+] = (unsigned char)((input[i] >> ) & 0xff);
output[j+] = (unsigned char)((input[i] >> ) & 0xff);
output[j+] = (unsigned char)((input[i] >> ) & 0xff);
}
} static void Decode (UINT32 *output, unsigned char *input, unsigned int len)
{
unsigned int i, j; for (i = , j = ; j < len; i++, j += )
output[i] = ((UINT32)input[j]) | (((UINT32)input[j+]) << ) |
(((UINT32)input[j+]) << ) | (((UINT32)input[j+]) << );
}

md5.h

#pragma once

typedef unsigned long int UINT32;
typedef unsigned short int UINT16; /* MD5 context. */
typedef struct {
UINT32 state[]; /* state (ABCD) */
UINT32 count[]; /* number of bits, modulo 2^64 (lsb first) */
unsigned char buffer[]; /* input buffer */
} MD5_CTX; void MD5Init (MD5_CTX *);
void MD5Update (MD5_CTX *, unsigned char *, unsigned int);
void MD5Final (unsigned char [], MD5_CTX *);

-------------------------------------------------------------------------------------------------------------------------

md5.h

#ifndef _MD5_H_
#define _MD5_H_ #define R_memset(x, y, z) memset(x, y, z)
#define R_memcpy(x, y, z) memcpy(x, y, z)
#define R_memcmp(x, y, z) memcmp(x, y, z) typedef unsigned long UINT4;
typedef unsigned char *POINTER; /* MD5 context. */
typedef struct {
/* state (ABCD) */
/*四个32bits数,用于存放最终计算得到的消息摘要。当消息长度〉512bits时,也用于存放每个512bits的中间结果*/
UINT4 state[]; /* number of bits, modulo 2^64 (lsb first) */
/*存储原始信息的bits数长度,不包括填充的bits,最长为 2^64 bits,因为2^64是一个64位数的最大值*/
UINT4 count[]; /* input buffer */
/*存放输入的信息的缓冲区,512bits*/
unsigned char buffer[];
} MD5_CTX; void MD5Init(MD5_CTX *);
void MD5Update(MD5_CTX *, unsigned char *, unsigned int);
void MD5Final(unsigned char [], MD5_CTX *); #endif /* _MD5_H_ */

md5.c

#include "MD5.H"
#include <string.h> /*md5转换用到的常量,算法本身规定的*/
#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 MD5Transform(UINT4 [], unsigned char []);
static void Encode(unsigned char *, UINT4 *, unsigned int);
static void Decode(UINT4 *, unsigned char *, unsigned int); /*
用于bits填充的缓冲区,为什么要64个字节呢?因为当欲加密的信息的bits数被512除其余数为448时,
需要填充的bits的最大值为512=64*8 。
*/
static unsigned char PADDING[] = {
0x80, , , , , , , , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , , , ,
}; /*
接下来的这几个宏定义是md5算法规定的,就是对信息进行md5加密都要做的运算。
据说有经验的高手跟踪程序时根据这几个特殊的操作就可以断定是不是用的md5
*/
/* 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. */
/*初始化md5的结构*/
void MD5Init (MD5_CTX *context)
{
/*将当前的有效信息的长度设成0,这个很简单,还没有有效信息,长度当然是0了*/
context->count[] = context->count[] = ; /* Load magic initialization constants.*/
/*初始化链接变量,算法要求这样,这个没法解释了*/
context->state[] = 0x67452301;
context->state[] = 0xefcdab89;
context->state[] = 0x98badcfe;
context->state[] = 0x10325476;
} /* MD5 block update operation. Continues an MD5 message-digest
operation, processing another message block, and updating the
context. */
/*将与加密的信息传递给md5结构,可以多次调用
context:初始化过了的md5结构
input:欲加密的信息,可以任意长
inputLen:指定input的长度
*/
void MD5Update(MD5_CTX *context,unsigned char * input,unsigned int inputLen)
{
unsigned int i, index, partLen; /* Compute number of bytes mod 64 */
/*计算已有信息的bits长度的字节数的模64, 64bytes=512bits。
用于判断已有信息加上当前传过来的信息的总长度能不能达到512bits,
如果能够达到则对凑够的512bits进行一次处理*/
index = (unsigned int)((context->count[] >> ) & 0x3F); /* Update number of bits *//*更新已有信息的bits长度*/
if((context->count[] += ((UINT4)inputLen << )) < ((UINT4)inputLen << ))
context->count[]++;
context->count[] += ((UINT4)inputLen >> ); /*计算已有的字节数长度还差多少字节可以 凑成64的整倍数*/
partLen = - index; /* Transform as many times as possible.
*/
/*如果当前输入的字节数 大于 已有字节数长度补足64字节整倍数所差的字节数*/
if(inputLen >= partLen) {
/*用当前输入的内容把context->buffer的内容补足512bits*/
R_memcpy((POINTER)&context->buffer[index], (POINTER)input, partLen);
/*用基本函数对填充满的512bits(已经保存到context->buffer中) 做一次转换,转换结果保存到context->state中*/
MD5Transform(context->state, context->buffer); /*
对当前输入的剩余字节做转换(如果剩余的字节<在输入的input缓冲区中>大于512bits的话 ),
转换结果保存到context->state中
*/
for(i = partLen; i + < inputLen; i += )/*把i+63<inputlen改为i+64<=inputlen更容易理解*/
MD5Transform(context->state, &input[i]); index = ;
} else
i = ; /* Buffer remaining input */
/*将输入缓冲区中的不足填充满512bits的剩余内容填充到context->buffer中,留待以后再作处理*/
R_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. */
/*获取加密 的最终结果
digest:保存最终的加密串
context:你前面初始化并填入了信息的md5结构
*/
void MD5Final (unsigned char digest[],MD5_CTX *context)
{
unsigned char bits[];
unsigned int index, padLen; /* Save number of bits */
/*将要被转换的信息(所有的)的bits长度拷贝到bits中*/
Encode(bits, context->count, ); /* Pad out to 56 mod 64. */
/* 计算所有的bits长度的字节数的模64, 64bytes=512bits*/
index = (unsigned int)((context->count[] >> ) & 0x3f);
/*计算需要填充的字节数,padLen的取值范围在1-64之间*/
padLen = (index < ) ? ( - index) : ( - index);
/*这一次函数调用绝对不会再导致MD5Transform的被调用,因为这一次不会填满512bits*/
MD5Update(context, PADDING, padLen); /* Append length (before padding) */
/*补上原始信息的bits长度(bits长度固定的用64bits表示),这一次能够恰巧凑够512bits,不会多也不会少*/
MD5Update(context, bits, ); /* Store state in digest */
/*将最终的结果保存到digest中。ok,终于大功告成了*/
Encode(digest, context->state, ); /* Zeroize sensitive information. */ R_memset((POINTER)context, , sizeof(*context));
} /* MD5 basic transformation. Transforms state based on block. */
/*
对512bits信息(即block缓冲区)进行一次处理,每次处理包括四轮
state[4]:md5结构中的state[4],用于保存对512bits信息加密的中间结果或者最终结果
block[64]:欲加密的512bits信息
*/
static void MD5Transform (UINT4 state[], unsigned char block[])
{
UINT4 a = state[], b = state[], c = state[], d = state[], x[]; Decode(x, block, ); /* Round 1 */
FF(a, b, c, d, x[ ], S11, 0xd76aa478); /* 1 */
FF(d, a, b, c, x[ ], S12, 0xe8c7b756); /* 2 */
FF(c, d, a, b, x[ ], S13, 0x242070db); /* 3 */
FF(b, c, d, a, x[ ], S14, 0xc1bdceee); /* 4 */
FF(a, b, c, d, x[ ], S11, 0xf57c0faf); /* 5 */
FF(d, a, b, c, x[ ], S12, 0x4787c62a); /* 6 */
FF(c, d, a, b, x[ ], S13, 0xa8304613); /* 7 */
FF(b, c, d, a, x[ ], S14, 0xfd469501); /* 8 */
FF(a, b, c, d, x[ ], S11, 0x698098d8); /* 9 */
FF(d, a, b, c, x[ ], S12, 0x8b44f7af); /* 10 */
FF(c, d, a, b, x[], S13, 0xffff5bb1); /* 11 */
FF(b, c, d, a, x[], S14, 0x895cd7be); /* 12 */
FF(a, b, c, d, x[], S11, 0x6b901122); /* 13 */
FF(d, a, b, c, x[], S12, 0xfd987193); /* 14 */
FF(c, d, a, b, x[], S13, 0xa679438e); /* 15 */
FF(b, c, d, a, x[], S14, 0x49b40821); /* 16 */ /* Round 2 */
GG(a, b, c, d, x[ ], S21, 0xf61e2562); /* 17 */
GG(d, a, b, c, x[ ], S22, 0xc040b340); /* 18 */
GG(c, d, a, b, x[], S23, 0x265e5a51); /* 19 */
GG(b, c, d, a, x[ ], S24, 0xe9b6c7aa); /* 20 */
GG(a, b, c, d, x[ ], S21, 0xd62f105d); /* 21 */
GG(d, a, b, c, x[], S22, 0x2441453); /* 22 */
GG(c, d, a, b, x[], S23, 0xd8a1e681); /* 23 */
GG(b, c, d, a, x[ ], S24, 0xe7d3fbc8); /* 24 */
GG(a, b, c, d, x[ ], S21, 0x21e1cde6); /* 25 */
GG(d, a, b, c, x[], S22, 0xc33707d6); /* 26 */
GG(c, d, a, b, x[ ], S23, 0xf4d50d87); /* 27 */
GG(b, c, d, a, x[ ], S24, 0x455a14ed); /* 28 */
GG(a, b, c, d, x[], S21, 0xa9e3e905); /* 29 */
GG(d, a, b, c, x[ ], S22, 0xfcefa3f8); /* 30 */
GG(c, d, a, b, x[ ], S23, 0x676f02d9); /* 31 */
GG(b, c, d, a, x[], S24, 0x8d2a4c8a); /* 32 */ /* Round 3 */
HH(a, b, c, d, x[ ], S31, 0xfffa3942); /* 33 */
HH(d, a, b, c, x[ ], S32, 0x8771f681); /* 34 */
HH(c, d, a, b, x[], S33, 0x6d9d6122); /* 35 */
HH(b, c, d, a, x[], S34, 0xfde5380c); /* 36 */
HH(a, b, c, d, x[ ], S31, 0xa4beea44); /* 37 */
HH(d, a, b, c, x[ ], S32, 0x4bdecfa9); /* 38 */
HH(c, d, a, b, x[ ], S33, 0xf6bb4b60); /* 39 */
HH(b, c, d, a, x[], S34, 0xbebfbc70); /* 40 */
HH(a, b, c, d, x[], S31, 0x289b7ec6); /* 41 */
HH(d, a, b, c, x[ ], S32, 0xeaa127fa); /* 42 */
HH(c, d, a, b, x[ ], S33, 0xd4ef3085); /* 43 */
HH(b, c, d, a, x[ ], S34, 0x4881d05); /* 44 */
HH(a, b, c, d, x[ ], S31, 0xd9d4d039); /* 45 */
HH(d, a, b, c, x[], S32, 0xe6db99e5); /* 46 */
HH(c, d, a, b, x[], S33, 0x1fa27cf8); /* 47 */
HH(b, c, d, a, x[ ], S34, 0xc4ac5665); /* 48 */ /* Round 4 */
II(a, b, c, d, x[ ], S41, 0xf4292244); /* 49 */
II(d, a, b, c, x[ ], S42, 0x432aff97); /* 50 */
II(c, d, a, b, x[], S43, 0xab9423a7); /* 51 */
II(b, c, d, a, x[ ], S44, 0xfc93a039); /* 52 */
II(a, b, c, d, x[], S41, 0x655b59c3); /* 53 */
II(d, a, b, c, x[ ], S42, 0x8f0ccc92); /* 54 */
II(c, d, a, b, x[], S43, 0xffeff47d); /* 55 */
II(b, c, d, a, x[ ], S44, 0x85845dd1); /* 56 */
II(a, b, c, d, x[ ], S41, 0x6fa87e4f); /* 57 */
II(d, a, b, c, x[], S42, 0xfe2ce6e0); /* 58 */
II(c, d, a, b, x[ ], S43, 0xa3014314); /* 59 */
II(b, c, d, a, x[], S44, 0x4e0811a1); /* 60 */
II(a, b, c, d, x[ ], S41, 0xf7537e82); /* 61 */
II(d, a, b, c, x[], S42, 0xbd3af235); /* 62 */
II(c, d, a, b, x[ ], S43, 0x2ad7d2bb); /* 63 */
II(b, c, d, a, x[ ], S44, 0xeb86d391); /* 64 */ state[] += a;
state[] += b;
state[] += c;
state[] += d; /* Zeroize sensitive information. */
R_memset((POINTER)x, , sizeof(x));
} /* Encodes input (UINT4) into output (unsigned char). Assumes len is
a multiple of 4. */
/*将4字节的整数copy到字符形式的缓冲区中
output:用于输出的字符缓冲区
input:欲转换的四字节的整数形式的数组
len:output缓冲区的长度,要求是4的整数倍
*/
static void Encode(unsigned char *output, UINT4 *input,unsigned int len)
{
unsigned int i, j; for(i = , j = ; j < len; i++, j += ) {
output[j] = (unsigned char)(input[i] & 0xff);
output[j+] = (unsigned char)((input[i] >> ) & 0xff);
output[j+] = (unsigned char)((input[i] >> ) & 0xff);
output[j+] = (unsigned char)((input[i] >> ) & 0xff);
}
} /* Decodes input (unsigned char) into output (UINT4). Assumes len is
a multiple of 4. */
/*与上面的函数正好相反,这一个把字符形式的缓冲区中的数据copy到4字节的整数中(即以整数形式保存)
output:保存转换出的整数
input:欲转换的字符缓冲区
len:输入的字符缓冲区的长度,要求是4的整数倍
*/
static void Decode(UINT4 *output, unsigned char *input,unsigned int len)
{
unsigned int i, j; for(i = , j = ; j < len; i++, j += )
output[i] = ((UINT4)input[j]) | (((UINT4)input[j+]) << ) |
(((UINT4)input[j+]) << ) | (((UINT4)input[j+]) << );
}

main.c

#include <stdio.h>
#include <string.h>
#include "MD5.H" int main(int argc, char* argv[])
{
int i;
MD5_CTX md5;
MD5Init(&md5); //初始化用于md5加密的结构 unsigned char encrypt[]; //存放于加密的信息
unsigned char decrypt[]; //存放加密后的结果
scanf("%s",encrypt); //输入加密的字符 MD5Update(&md5,encrypt,strlen((char *)encrypt)); //对欲加密的字符进行加密
MD5Final(decrypt,&md5); //获得最终结果 printf("加密前:%s\n加密后:",encrypt);
for(i=; i<; i++)
{
printf("%2x ",decrypt[i]);
} printf("\n\n\n加密结束!\n"); return ;
}

md5代码实现的更多相关文章

  1. javascript 的MD5代码备份,跟java互通

    var MD5 = function (string) {                   function RotateLeft(lValue, iShiftBits) {            ...

  2. OpenSSL - 文件和字符MD5加密实现

    OpenSSL安装: 1.github下载最新的OpenSSL:https://github.com/openssl/openssl 2.在linux解压压缩包 3.安装OpenSSL ./confi ...

  3. 2 MD5加密 java实现

    百度百科对MD5的说明是: Message Digest Algorithm MD5(中文名为消息摘要算法第 五版)为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护. MD5即Mess ...

  4. Md5的加密 java实现

    百度百科对MD5的说明是: Message Digest Algorithm MD5(中文名为消息摘要算法第 五版)为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护. MD5即Mess ...

  5. 获取txt md5值上传文件完整性校验

    网络上传文件到服务器 做md5 校对.判断文件是否破坏 首先求txt文件的md5值 ,1万条数据 求出的值 文件MD5:e5467b6a8e3c26af8c5af0bda3739280 服务器处理程序 ...

  6. vim 文本会在末尾自动添加换行 md5文件和数据只不对应

    在linux系统 vim md5data  # 打开文件 写入 abc 保存 md5sum md5Data  的计算值和openssl代码计算值不一样 原因在于linux文本文件末尾自动添加了换行 解 ...

  7. 加密算法之 MD5算法

    题记:本人自测了很多次,该算法和apache的commons utils包中的MD5算法计算一致 一.针对文件内容生成MD5值 应用场景:针对文件,在传输过程由于网络原因丢帧或者被人别恶意篡改内容,可 ...

  8. cryptopp开源库的使用(二):base64加密

    很多时候我只是优秀工具的使用者,优秀的工具用好了才能发挥作用 最近使用cryptopp的base64对压缩后的zip文件内容进行加密遇到了问题. 首先zip压缩没问题,可是最后得到的base64字符串 ...

  9. 初学Python——Socket网络编程

    认识socket socket本质上就是在2台网络互通的电脑之间,架设一个通道,两台电脑通过这个通道来实现数据的互相传递.我们知道网络 通信 都 是基于 ip+port(端口) 方能定位到目标的具体机 ...

随机推荐

  1. 【HDU5772】String Problem [网络流]

    String Problem Time Limit: 10 Sec  Memory Limit: 64 MB[Submit][Status][Discuss] Description Input Ou ...

  2. bzoj3223 文艺平衡树 codevs3303 翻转区间

    splay模版题吧 只有区间翻转 至于为什么要把须翻转区间旋到根 因为查找一个区间可以先找出他左端点左边第一个点和右端点x右边第一个点y 然后将x旋到根节点 y旋到x的右儿子 这样x的右边的点就是所有 ...

  3. hdu 2817 A sequence of numbers(快速幂取余)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2817 题目大意:给出三个数,来判断是等差还是等比数列,再输入一个n,来计算第n个数的值. #inclu ...

  4. System and method for parallel execution of memory transactions using multiple memory models, including SSO, TSO, PSO and RMO

    A data processor supports the use of multiple memory models by computer programs. At a device extern ...

  5. golang写一个简单的爬虫

    package main import( "fmt" "io/ioutil" "net/http" ) func gethtml(url s ...

  6. linux用grep查找包含两个关键字的命令

    linux用grep查找包含两个关键字的命令 http://zhidao.baidu.com/link?url=VsFxeJXmU7W7hy1UH7eT6QAbUsVz9Ru2ABPuWYHWm4kB ...

  7. win32 sdk列表视图控件(ListCtrl或ListView)资料整理

    列表视图控件是一种非常常用的控件,在需要以报表形式显示数据时,列表控件通常是最好的选择,许多专用的数据报表控件,也是在它的基础上派生而来.与树视图类似,列表控件可以由多个子项目组成,可以设置为Icon ...

  8. selenium 截图 添加时间戳

    在自动化程序中运行的代码报错信息或者是相关日志有可能并无法直观的判断出错信息.因此截图是避免不了的.为了避免因为重复运行或者是图片名称相同导致截图被覆盖. 建议在截图时使用时间戳,保证截图图片名称的唯 ...

  9. 对数据访问层的重构(及重构中Perl的应用)

    以前上学的时候,听到“一个学生在毕业后刚刚开始编程的头几年中,写出的代码多半是垃圾”这样的说法,均不屑一顾.现在工作一年多了,越发感觉自己代码中疏漏处甚多,故近来常做亡羊补牢的重构之举.拿自己4个月前 ...

  10. jQuery验证控件jquery.validate.js使用说明+中文API(转)

    一导入js库<script src="../js/jquery.js" type="text/javascript"></script> ...