md5算法的C程序

来源:互联网 发布:淘宝我的回答能删除么 编辑:程序博客网 时间:2024/06/11 18:47

         最近看项目代码,需要用到md5加密算法,颇为好奇,遂看看。md5算法,其实就是message digest 算法, message是输入,digest是输出。下面会给出md5算法的C程序,已经和百度提供的md5计算工具进行了对比,完全一致。我参考了网上的程序,整理出下面的程序。

        说明:程序有点小复杂,也花了不少时间来整理程序格式,让其好看点。这完全是怀着对md5算法的兴趣,尤其是对山东大学的王小云女士的崇拜(md5和sha-1算法的破密者)。

        废话少说, 等下要出去玩呢,直接上代码:

#include <stdio.h>    #include <string.h>   typedef unsigned char *POINTER;   typedef unsigned short int UINT2;   typedef unsigned long int UINT4;   typedef struct     {   UINT4 state[4];   UINT4 count[2];   unsigned char buffer[64];   }MD5_CTX;   void MD5Init(MD5_CTX*);   void MD5Update(MD5_CTX*, unsigned char*, unsigned int);   void MD5Final(unsigned char[], MD5_CTX*);   #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 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   };   #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) + (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); }   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);   }   }   // 对input进行解析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);   }}   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);   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   */   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   */   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   */   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;   memset((POINTER)x, 0, sizeof (x));   }   void MD5Init(MD5_CTX *context)   {   context->count[0] = context->count[1] = 0;   context->state[0] = 0x67452301;   context->state[1] = 0xefcdab89;   context->state[2] = 0x98badcfe;   context->state[3] = 0x10325476;   }   void MD5Update(MD5_CTX *context, unsigned char *input, unsigned int inputLen)   {   unsigned int i, index, partLen;   index = (unsigned int)((context->count[0] >> 3) & 0x3F);   if((context->count[0] += ((UINT4)inputLen << 3)) < ((UINT4)inputLen   <<   3)){context->count[1]++;}context->count[1] += ((UINT4)inputLen >> 29);   partLen = 64 - index;   if(inputLen >= partLen)   {   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;  }memcpy((POINTER)&context->buffer[index], (POINTER)&input[i], inputLen - i);   }   void MD5Final(unsigned char digest[16], MD5_CTX *context)   {   unsigned char bits[8];   unsigned int  index, padLen;   Encode(bits, context->count, 8);   index = (unsigned int)((context->count[0] >> 3) & 0x3f);   padLen = (index < 56) ? (56 - index) : (120 - index);   MD5Update(context, PADDING, padLen);   MD5Update(context, bits, 8);   Encode(digest, context->state, 16);   memset((POINTER)context, 0, sizeof(*context));   }   void MD5Digest(char *pszInput, unsigned long nInputSize, char *pszOutPut)   {   MD5_CTX  context;   unsigned int len = strlen(pszInput);   MD5Init(&context);   MD5Update(&context,(unsigned char *)pszInput, len);   MD5Final((unsigned char *)pszOutPut, &context);   }   int main()   {char szDigest[16];   char encrypt[200];  while(1){printf("输入要计算MD5值的字符串:");gets(encrypt);printf("加密结果:");  MD5Digest(encrypt, strlen(encrypt), szDigest); int i;for (i = 0; i < 16; i++) // 32位 {printf("%02X",(unsigned char)szDigest[i]); // 注意,不是%X}printf("\n");}return 0;}

原创粉丝点击