Chinaunix首页 | 论坛 | 博客
  • 博客访问: 390275
  • 博文数量: 62
  • 博客积分: 388
  • 博客等级: 一等列兵
  • 技术积分: 1032
  • 用 户 组: 普通用户
  • 注册时间: 2012-02-03 20:18
文章分类

全部博文(62)

文章存档

2017年(5)

2016年(3)

2015年(3)

2014年(8)

2013年(15)

2012年(28)

分类: C/C++

2012-06-01 16:42:22

MD5数字签名 针对字符串 或 文件 生成32位字符的签名 比较两个文件或字符串 只需比较MD5签名就行了 能迅速比较出两个字符串或文件的异同。看代码吧

点击(此处)折叠或打开

  1. ifndef __HAVE_MD5_H__

  2. #define __HAVE_MD5_H__


  3. #ifndef PROTOTYPES

  4. #define PROTOTYPES 0

  5. #endif


  6. #if PROTOTYPES

  7. #define PROTO_LIST(list) list

  8. #else

  9. #define PROTO_LIST(list) ()

  10. #endif


  11. /* 定义POINTER类型 */

  12. typedef unsigned char *POINTER;


  13. /* 定义UINT2类型 */

  14. typedef unsigned short int UINT2;


  15. /* 定义UINT4类型 */

  16. typedef unsigned long int UINT4;


  17. /* MD5上下文 */

  18. typedef struct
  19. {

  20.   UINT4 state[4];

  21.   UINT4 count[2];
  22.   unsigned char buffer[64]; /* 输入缓冲区 */

  23. } MD5_CTX;


  24. void MD5Init PROTO_LIST((MD5_CTX *));

  25. void MD5Update PROTO_LIST((MD5_CTX *, unsigned char *, unsigned int));

  26. void MD5Final PROTO_LIST((unsigned char [16], MD5_CTX *));


  27. #endif

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

点击(此处)折叠或打开

  1. #include "md5.h"


  2. /*

  3. * MD5Transform函数中的常量
  4. */

  5. #define S11 7

  6. #define S12 12

  7. #define S13 17

  8. #define S14 22

  9. #define S21 5

  10. #define S22 9

  11. #define S23 14

  12. #define S24 20

  13. #define S31 4

  14. #define S32 11

  15. #define S33 16

  16. #define S34 23

  17. #define S41 6

  18. #define S42 10

  19. #define S43 15

  20. #define S44 21


  21. static void MD5Transform PROTO_LIST((UINT4 [4], unsigned char [64]));

  22. static void Encode PROTO_LIST((unsigned char *, UINT4 *, unsigned int));

  23. static void Decode PROTO_LIST((UINT4 *, unsigned char *, unsigned int));

  24. static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));

  25. static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));


  26. static unsigned char PADDING[64] =
  27. {

  28.   0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

  29.   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

  30.   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0

  31. };


  32. /*
  33. * F, G, H and I MD5基本功能函数

  34. */

  35. #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))

  36. #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))

  37. #define H(x, y, z) ((x) ^ (y) ^ (z))

  38. #define I(x, y, z) ((y) ^ ((x) | (~z)))


  39. /*
  40. * ROTATE_LEFT 旋转x的左边bits

  41. */

  42. #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))


  43. #define FF(a, b, c, d, x, s, ac) { \

  44. (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \

  45. (a) = ROTATE_LEFT ((a), (s)); \

  46. (a) += (b); \

  47.   }

  48. #define GG(a, b, c, d, x, s, ac) { \

  49. (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \

  50. (a) = ROTATE_LEFT ((a), (s)); \

  51. (a) += (b); \

  52.   }

  53. #define HH(a, b, c, d, x, s, ac) { \

  54. (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \

  55. (a) = ROTATE_LEFT ((a), (s)); \

  56. (a) += (b); \

  57.   }

  58. #define II(a, b, c, d, x, s, ac) { \

  59. (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \

  60. (a) = ROTATE_LEFT ((a), (s)); \

  61. (a) += (b); \

  62.   }


  63. /*

  64. * MD5Init: MD5初始化,开始MD5的新操作

  65. *
  66. * @context:MD5参数

  67. *

  68. * @return:

  69. */

  70. void MD5Init(MD5_CTX *context)

  71. {

  72.   context->count[0] = context->count[1] = 0;

  73.   /* 载入MD5常量 */

  74.   context->state[0] = 0x67452301;

  75.   context->state[1] = 0xefcdab89;

  76.   context->state[2] = 0x98badcfe;

  77.   context->state[3] = 0x10325476;

  78. }


  79. /*
  80. * MD5Update:MD5块更新操作,持续的MD5消息摘要操作,处理另一个消息块,并更新上下文

  81. *

  82. * @content:摘要信息块

  83. * @input:输入信息快

  84. * @inputLen:输入信息块长度

  85. *

  86. * @return:

  87. */

  88. void MD5Update (MD5_CTX *context, unsigned char *input, unsigned int inputLen)

  89. {

  90.   unsigned int i, index, partLen;


  91.   /* 计算64位的信息摘要 */

  92.   index = (unsigned int)((context->count[0] >> 3) & 0x3F);


  93.   /* 更新数据位 */

  94.   if((context->count[0] += ((UINT4)inputLen << 3)) < ((UINT4)inputLen << 3))

  95.         context->count[1]++;

  96.   context->count[1] += ((UINT4)inputLen >> 29);


  97.   partLen = 64 - index;


  98.   /* 转化可能多的次数 */

  99.   if (inputLen >= partLen)
  100.   {

  101.         MD5_memcpy((POINTER)&context->buffer[index], (POINTER)input, partLen);

  102.     MD5Transform (context->state, context->buffer);


  103.     for (i = partLen; i + 63 < inputLen; i += 64)

  104.                 MD5Transform (context->state, &input[i]);


  105.         index = 0;

  106.   }

  107.   else

  108.   {

  109.         i = 0;

  110.   }


  111.   /* 缓冲区中的剩余输入 */

  112.   MD5_memcpy((POINTER)&context->buffer[index], (POINTER)&input[i],inputLen-i);

  113. }


  114. /*
  115. * MD5Final:完成MD5信息摘要操作,书写消息摘要和初始化上下文

  116. *

  117. * @digest:信息摘要

  118. * @content:信息块

  119. *

  120. * @return:

  121. */

  122. void MD5Final(unsigned char digest[16], MD5_CTX *context)

  123. {

  124.   unsigned char bits[8];

  125.   unsigned int index, padLen;


  126.   /* 保存数字摘要位 */

  127.   Encode (bits, context->count, 8);


  128.   /* 填充56位到64位 */

  129.   index = (unsigned int)((context->count[0] >> 3) & 0x3f);

  130.   padLen = (index < 56) ? (56 - index) : (120 - index);

  131.   MD5Update (context, PADDING, padLen);


  132.   /* 添加长度 */

  133.   MD5Update (context, bits, 8);

  134.   /* 存储摘要 */

  135.   Encode (digest, context->state, 16);


  136.   /* 清零摘要上下文 */

  137.   MD5_memset ((POINTER)context, 0, sizeof (*context));

  138. }


  139. /*
  140. * MD5Transform:MD5基本转化

  141. *

  142. * @state:基本状态转化

  143. * @block:转化数据块

  144. *

  145. * @return:

  146. */

  147. static void MD5Transform (UINT4 state[4], unsigned char block[64])

  148. {

  149.   UINT4 a, b, c, d, x[16];


  150.   a = state[0];

  151.   b = state[1];

  152.   c = state[2];

  153.   d = state[3];

  154.   

  155.   Decode (x, block, 64);


  156.   /* 第一轮 */

  157.   FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */

  158.   FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */

  159.   FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */

  160.   FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */

  161.   FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */

  162.   FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */

  163.   FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */

  164.   FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */

  165.   FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */

  166.   FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */

  167.   FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */

  168.   FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */

  169.   FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */

  170.   FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */

  171.   FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */

  172.   FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */


  173. /* 第二轮 */

  174.   GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */

  175.   GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */

  176.   GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */

  177.   GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */

  178.   GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */

  179.   GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */

  180.   GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */

  181.   GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */

  182.   GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */

  183.   GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */

  184.   GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */

  185.   GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */

  186.   GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */

  187.   GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */

  188.   GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */

  189.   GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */


  190.   /* 第三轮 */

  191.   HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */

  192.   HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */

  193.   HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */

  194.   HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */

  195.   HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */

  196.   HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */

  197.   HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */

  198.   HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */

  199.   HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */

  200.   HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */

  201.   HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */

  202.   HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */

  203.   HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */

  204.   HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */

  205.   HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */

  206.   HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */


  207.   /* 第四轮 */

  208.   II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */

  209.   II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */

  210.   II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */

  211.   II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */

  212.   II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */

  213.   II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */

  214.   II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */

  215.   II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */

  216.   II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */

  217.   II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */

  218.   II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */

  219.   II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */

  220.   II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */

  221.   II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */

  222.   II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */

  223.   II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */


  224.   state[0] += a;

  225.   state[1] += b;

  226.   state[2] += c;

  227.   state[3] += d;


  228.   MD5_memset ((POINTER)x, 0, sizeof (x));

  229. }


  230. /* Encodes input (UINT4) into output (unsigned char). Assumes len is

  231.   a multiple of 4.

  232. */

  233. static void Encode(unsigned char *output, UINT4 *input, unsigned int len)

  234. {

  235.   unsigned int i, j;


  236.   for (i = 0, j = 0; j < len; i++, j += 4)
  237.   {

  238.         output[j] = (unsigned char)(input[i] & 0xff);

  239.         output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);

  240.         output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);

  241.         output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);

  242.   }

  243. }


  244. /*

  245. * Decode: 解码(unsigned char)到输出(UINT4)

  246. *
  247. * @output:输出串

  248. * @input:输入串

  249. * @len:输入串长度

  250. *

  251. * @return:
  252. */

  253. static void Decode(UINT4 *output, unsigned char *input, unsigned int len)

  254. {

  255.   unsigned int i, j;


  256.   for (i = 0, j = 0; j < len; i++, j += 4)

  257.         output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | ((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);

  258. }


  259. /*
  260. * MD5_memcpy:字符串拷贝

  261. *

  262. * @output:输出字符串

  263. * @input:输入字符串

  264. * @len:字符串的长度

  265. *

  266. * @return:

  267. */

  268. static void MD5_memcpy (POINTER output, POINTER input, unsigned int len)

  269. {

  270.   unsigned int i;


  271.   for (i = 0; i < len; i++)

  272.         output[i] = input[i];

  273. }


  274. /*
  275. * MD5_memset:这个都知道

  276. *

  277. * @output:输出字符串

  278. * @value:赋值

  279. * @len:输出字符串的长度

  280. *

  281. * @return:

  282. */

  283. static void MD5_memset (POINTER output, int value, unsigned int len)

  284. {

  285.   unsigned int i;


  286.   for (i = 0; i < len; i++)

  287.         ((char *)output)[i] = (char)value;

  288. }


 

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


 

点击(此处)折叠或打开

  1. #ifndef MD

  2. #define MD5 5

  3. #define MD MD5

  4. #endif


  5. #include <stdio.h>

  6. #include <time.h>

  7. #include <string.h>

  8. #if MD == 2

  9. #include "md2.h"

  10. #endif

  11. #if MD == 4

  12. #include "md4.h"

  13. #endif

  14. #if MD == 5

  15. #include "md5.h"

  16. #endif


  17. #define TEST_BLOCK_LEN 1500

  18. #define TEST_BLOCK_COUNT 1500


  19. static void MDString PROTO_LIST ((char *));

  20. static void MDTimeTrial PROTO_LIST ((void));

  21. static void MDTestSuite PROTO_LIST ((void));

  22. static void MDFile PROTO_LIST ((char *));

  23. static void MDFilter PROTO_LIST ((void));

  24. static void MDPrint PROTO_LIST ((unsigned char [16]));


  25. #if MD == 2

  26. #define MD_CTX MD2_CTX

  27. #define MDInit MD2Init

  28. #define MDUpdate MD2Update

  29. #define MDFinal MD2Final

  30. #endif

  31. #if MD == 4

  32. #define MD_CTX MD4_CTX

  33. #define MDInit MD4Init

  34. #define MDUpdate MD4Update

  35. #define MDFinal MD4Final

  36. #endif

  37. #if MD == 5

  38. #define MD_CTX MD5_CTX

  39. #define MDInit MD5Init

  40. #define MDUpdate MD5Update

  41. #define MDFinal MD5Final

  42. #endif


  43. /* Main driver.


  44. Arguments (may be any combination):

  45.   -sstring - 摘要串

  46.   -t - 运行时间测试

  47.   -x - 运行测试脚本

  48.   filename - 摘要文件

  49.   (none) - 摘要标准输入

  50. */

  51. int main (int argc, char *argv[])

  52. {

  53.   int i;


  54.   if (argc > 1)

  55. for (i = 1; i < argc; i++)

  56.    if (argv[i][0] == '-' && argv[i][1] == 's')

  57.      MDString (argv[i] + 2);

  58.    else if (strcmp (argv[i], "-t") == 0)

  59.      MDTimeTrial ();

  60.    else if (strcmp (argv[i], "-x") == 0)

  61.      MDTestSuite ();

  62.    else

  63.      MDFile (argv[i]);

  64.   else

  65. MDFilter ();


  66.   return (0);

  67. }


  68. /*

  69. * MDString:将字符串转化为MD5字符串(摘要串)

  70. *

  71. * @string:被摘要的字符串

  72. *

  73. * @return:

  74. *

  75. * NOTE:将字符串转化为摘要串并输出,用的选项为-s

  76. */

  77. static void MDString(char *string)

  78. {

  79.   MD_CTX context;

  80.   unsigned char digest[16];

  81.   unsigned int len = strlen(string);


  82.   MDInit(&context);

  83.   MDUpdate(&context, string, len);

  84.   MDFinal(digest, &context);


  85.   printf ("MD%d (\"%s\") = ", MD, string);

  86.   MDPrint (digest);

  87.   printf ("\n");

  88. }


  89. /*
  90. * MDTimeTrial:摘要时间测试并输出

  91. *

  92. * @return:

  93. */

  94. static void MDTimeTrial()

  95. {

  96.   MD_CTX context;

  97.   time_t endTime, startTime;

  98.   unsigned char block[TEST_BLOCK_LEN], digest[16];

  99.   unsigned int i;

  100.   printf("MD%d time trial. Digesting %d %d-byte blocks ...", MD,

  101.   TEST_BLOCK_LEN, TEST_BLOCK_COUNT);


  102.   /* 初始化数据块 */

  103.   for (i = 0; i < TEST_BLOCK_LEN; i++)

  104.         block[i] = (unsigned char)(i & 0xff);


  105.   /* 开始时间 */

  106.   time (&startTime);


  107.   /* 摘要信息块 */

  108.   MDInit (&context);

  109.   for (i = 0; i < TEST_BLOCK_COUNT; i++)

  110.         MDUpdate (&context, block, TEST_BLOCK_LEN);

  111.   MDFinal (digest, &context);


  112.   /* 停止时间 */

  113.   time (&endTime);


  114.   printf ("done\n");

  115.   printf ("Digest = ");

  116.   MDPrint (digest);

  117.   printf ("\nTime = %ld seconds\n", (long)(endTime-startTime));

  118.   printf ("Speed = %ld bytes/second\n",

  119.          (long)TEST_BLOCK_LEN * (long)TEST_BLOCK_COUNT/(endTime-startTime));

  120. }


  121. /*
  122. * MDTestSuite:测试MDString,测试脚本

  123. *

  124. * @return:

  125. */

  126. static void MDTestSuite()

  127. {

  128.   printf ("MD%d test suite:\n", MD);


  129.   MDString ("");

  130.   MDString ("a");

  131.   MDString ("abc");

  132.   MDString ("message digest");

  133.   MDString ("abcdefghijklmnopqrstuvwxyz");

  134.   MDString ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");

  135.   MDString ("1234567890123456789012345678901234567890\

  136.              1234567890123456789012345678901234567890");

  137. }


  138. /*

  139. * MDFile:摘要文件并输出

  140. *

  141. * @filename:摘要文件名称

  142. *

  143. * @return:

  144. */

  145. static void MDFile(char *filename)

  146. {

  147.   FILE *file;

  148.   MD_CTX context;

  149.   int len;

  150.   unsigned char buffer[1024], digest[16];


  151.   if ((file = fopen (filename, "rb")) == NULL)

  152.         printf ("%s can't be opened\n", filename);


  153.   else
  154.   {

  155.                 MDInit (&context);

  156.                 while (len = fread (buffer, 1, 1024, file))

  157.                         MDUpdate (&context, buffer, len);

  158.                 MDFinal (digest, &context);


  159.                 fclose (file);


  160.                 printf ("MD%d (%s) = ", MD, filename);

  161.                 MDPrint (digest);

  162.                 printf ("\n");

  163.   }

  164. }


  165. /*
  166. * MDFilter:摘要标准输入

  167. *

  168. * @return:

  169. */

  170. static void MDFilter()

  171. {

  172.   MD_CTX context;

  173.   int len;

  174.   unsigned char buffer[16], digest[16];


  175.   MDInit (&context);

  176.   while (len = fread (buffer, 1, 16, stdin))

  177.         MDUpdate (&context, buffer, len);

  178.   MDFinal (digest, &context);


  179.   MDPrint (digest);

  180.   printf ("\n");

  181. }


  182. /*

  183. * MDPrint:以16进制输出信息摘要

  184. *

  185. * @digest:摘要信息

  186. *

  187. * @return:
  188. */

  189. static void MDPrint(unsigned char digest[16])

  190. {

  191.   unsigned int i;


  192.   for (i = 0; i < 16; i++)

  193.         printf ("%02x", digest[i]);

  194. }

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

阅读(7505) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~