Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4230866
  • 博文数量: 776
  • 博客积分: 13014
  • 博客等级: 上将
  • 技术积分: 10391
  • 用 户 组: 普通用户
  • 注册时间: 2010-02-22 17:00
文章分类

全部博文(776)

文章存档

2015年(55)

2014年(43)

2013年(147)

2012年(20)

2011年(82)

2010年(429)

md5

分类: C/C++

2010-11-30 16:12:53

 

  1. /* typedef a 32 bit type */
  2. typedef unsigned long int UINT4;
  3. /* Data structure for MD5 (Message Digest) computation */
  4. typedef struct {
  5.         UINT4 i[2]; /* number of _bits_ handled mod 2^64 */
  6.         UINT4 buf[4]; /* scratch buffer */
  7.         unsigned char in[64]; /* input buffer */
  8.         unsigned char digest[16]; /* actual digest after MD5Final call */
  9. } MD5_CTX;

  10. void MD5Init ();
  11. void MD5Update ();
  12. void MD5Final ();
  13. /* forward declaration */
  14. static void Transform ();

  15. static unsigned char PADDING[64] = {
  16.         0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  17.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  18.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  19.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  20.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  21.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  22.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  23.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  24. };

  25. /* F, G and H are basic MD5 functions: selection, majority, parity */
  26. #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
  27. #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
  28. #define H(x, y, z) ((x) ^ (y) ^ (z))
  29. #define I(x, y, z) ((y) ^ ((x) | (~z)))
  30. /* ROTATE_LEFT rotates x left n bits */
  31. #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
  32. /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */
  33. /* Rotation is separate from addition to prevent recomputation */
  34. #define FF(a, b, c, d, x, s, ac) \
  35.   {(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
  36.    (a) = ROTATE_LEFT ((a), (s)); \
  37.    (a) += (b); \
  38.   }
  39. #define GG(a, b, c, d, x, s, ac) \
  40.   {(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
  41.    (a) = ROTATE_LEFT ((a), (s)); \
  42.    (a) += (b); \
  43.   }
  44. #define HH(a, b, c, d, x, s, ac) \
  45.   {(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
  46.    (a) = ROTATE_LEFT ((a), (s)); \
  47.    (a) += (b); \
  48.   }
  49. #define II(a, b, c, d, x, s, ac) \
  50.   {(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
  51.    (a) = ROTATE_LEFT ((a), (s)); \
  52.    (a) += (b); \
  53.   }

  54. void MD5Init (MD5_CTX *mdContext)
  55. {
  56.         mdContext->i[0] = mdContext->i[1] = (UINT4)0;
  57.         /* Load magic initialization constants.
  58.         */
  59.         mdContext->buf[0] = (UINT4)0x67452301;
  60.         mdContext->buf[1] = (UINT4)0xefcdab89;
  61.         mdContext->buf[2] = (UINT4)0x98badcfe;
  62.         mdContext->buf[3] = (UINT4)0x10325476;
  63. }

  64. void MD5Update (MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen)
  65. {
  66.         UINT4 in[16];
  67.         int mdi;
  68.         unsigned int i, ii;
  69.         /* compute number of bytes mod 64 */
  70.         mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
  71.         /* update number of bits */
  72.         if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0])
  73.         {
  74.                 mdContext->i[1]++;
  75.         }
  76.         mdContext->i[0] += ((UINT4)inLen << 3);
  77.         mdContext->i[1] += ((UINT4)inLen >> 29);
  78.         while (inLen--)
  79.         {
  80.                 /* add new character to buffer, increment mdi */
  81.                 mdContext->in[mdi++] = *inBuf++;
  82.                 /* transform if necessary */
  83.                 if (mdi == 0x40)
  84.                 {
  85.                         for (i = 0, ii = 0; i < 16; i++, ii += 4)
  86.                         {
  87.                                 in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
  88.                                 (((UINT4)mdContext->in[ii+2]) << 16) |
  89.                                 (((UINT4)mdContext->in[ii+1]) << 8) |
  90.                                 ((UINT4)mdContext->in[ii]);
  91.                         }
  92.                         Transform (mdContext->buf, in);
  93.                         mdi = 0;
  94.                 } // end if

  95.         } // end while

  96. }

  97. void MD5Final (MD5_CTX *mdContext)
  98. {
  99.         UINT4 in[16];
  100.         int mdi;
  101.         unsigned int i, ii;
  102.         unsigned int padLen;
  103.         /* save number of bits */
  104.         in[14] = mdContext->i[0];
  105.         in[15] = mdContext->i[1];
  106.         /* compute number of bytes mod 64 */
  107.         mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
  108.         /* pad out to 56 mod 64 */
  109.         padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
  110.         MD5Update (mdContext, PADDING, padLen);
  111.         /* append length in bits and transform */
  112.         for (i = 0, ii = 0; i < 14; i++, ii += 4)
  113.         {
  114.                 in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
  115.                 (((UINT4)mdContext->in[ii+2]) << 16) |
  116.                 (((UINT4)mdContext->in[ii+1]) << 8) |
  117.                 ((UINT4)mdContext->in[ii]);
  118.         }
  119.         Transform (mdContext->buf, in);
  120.         /* store buffer in digest */
  121.         for (i = 0, ii = 0; i < 4; i++, ii += 4)
  122.         {
  123.                 mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF);
  124.                 mdContext->digest[ii+1] = (unsigned char)((mdContext->buf[i] >> 8) & 0xFF);
  125.                 mdContext->digest[ii+2] = (unsigned char)((mdContext->buf[i] >> 16) & 0xFF);
  126.                 mdContext->digest[ii+3] = (unsigned char)((mdContext->buf[i] >> 24) & 0xFF);
  127.         } // end for

  128. }

  129. /* Basic MD5 step. Transform buf based on in.
  130.  */
  131. static void Transform (UINT4 *buf, UINT4 *in)
  132. {
  133.     UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
  134.     /* Round 1 */
  135. #define S11 7
  136. #define S12 12
  137. #define S13 17
  138. #define S14 22
  139.     FF ( a, b, c, d, in[ 0], S11, 3614090360); /* 1 */
  140.     FF ( d, a, b, c, in[ 1], S12, 3905402710); /* 2 */
  141.     FF ( c, d, a, b, in[ 2], S13, 606105819); /* 3 */
  142.     FF ( b, c, d, a, in[ 3], S14, 3250441966); /* 4 */
  143.     FF ( a, b, c, d, in[ 4], S11, 4118548399); /* 5 */
  144.     FF ( d, a, b, c, in[ 5], S12, 1200080426); /* 6 */
  145.     FF ( c, d, a, b, in[ 6], S13, 2821735955); /* 7 */
  146.     FF ( b, c, d, a, in[ 7], S14, 4249261313); /* 8 */
  147.     FF ( a, b, c, d, in[ 8], S11, 1770035416); /* 9 */
  148.     FF ( d, a, b, c, in[ 9], S12, 2336552879); /* 10 */
  149.     FF ( c, d, a, b, in[10], S13, 4294925233); /* 11 */
  150.     FF ( b, c, d, a, in[11], S14, 2304563134); /* 12 */
  151.     FF ( a, b, c, d, in[12], S11, 1804603682); /* 13 */
  152.     FF ( d, a, b, c, in[13], S12, 4254626195); /* 14 */
  153.     FF ( c, d, a, b, in[14], S13, 2792965006); /* 15 */
  154.     FF ( b, c, d, a, in[15], S14, 1236535329); /* 16 */
  155.     /* Round 2 */
  156. #define S21 5
  157. #define S22 9
  158. #define S23 14
  159. #define S24 20
  160.     GG ( a, b, c, d, in[ 1], S21, 4129170786); /* 17 */
  161.     GG ( d, a, b, c, in[ 6], S22, 3225465664); /* 18 */
  162.     GG ( c, d, a, b, in[11], S23, 643717713); /* 19 */
  163.     GG ( b, c, d, a, in[ 0], S24, 3921069994); /* 20 */
  164.     GG ( a, b, c, d, in[ 5], S21, 3593408605); /* 21 */
  165.     GG ( d, a, b, c, in[10], S22, 38016083); /* 22 */
  166.     GG ( c, d, a, b, in[15], S23, 3634488961); /* 23 */
  167.     GG ( b, c, d, a, in[ 4], S24, 3889429448); /* 24 */
  168.     GG ( a, b, c, d, in[ 9], S21, 568446438); /* 25 */
  169.     GG ( d, a, b, c, in[14], S22, 3275163606); /* 26 */
  170.     GG ( c, d, a, b, in[ 3], S23, 4107603335); /* 27 */
  171.     GG ( b, c, d, a, in[ 8], S24, 1163531501); /* 28 */
  172.     GG ( a, b, c, d, in[13], S21, 2850285829); /* 29 */
  173.     GG ( d, a, b, c, in[ 2], S22, 4243563512); /* 30 */
  174.     GG ( c, d, a, b, in[ 7], S23, 1735328473); /* 31 */
  175.     GG ( b, c, d, a, in[12], S24, 2368359562); /* 32 */
  176.     /* Round 3 */
  177. #define S31 4
  178. #define S32 11
  179. #define S33 16
  180. #define S34 23
  181.     HH ( a, b, c, d, in[ 5], S31, 4294588738); /* 33 */
  182.     HH ( d, a, b, c, in[ 8], S32, 2272392833); /* 34 */
  183.     HH ( c, d, a, b, in[11], S33, 1839030562); /* 35 */
  184.     HH ( b, c, d, a, in[14], S34, 4259657740); /* 36 */
  185.     HH ( a, b, c, d, in[ 1], S31, 2763975236); /* 37 */
  186.     HH ( d, a, b, c, in[ 4], S32, 1272893353); /* 38 */
  187.     HH ( c, d, a, b, in[ 7], S33, 4139469664); /* 39 */
  188.     HH ( b, c, d, a, in[10], S34, 3200236656); /* 40 */
  189.     HH ( a, b, c, d, in[13], S31, 681279174); /* 41 */
  190.     HH ( d, a, b, c, in[ 0], S32, 3936430074); /* 42 */
  191.     HH ( c, d, a, b, in[ 3], S33, 3572445317); /* 43 */
  192.     HH ( b, c, d, a, in[ 6], S34, 76029189); /* 44 */
  193.     HH ( a, b, c, d, in[ 9], S31, 3654602809); /* 45 */
  194.     HH ( d, a, b, c, in[12], S32, 3873151461); /* 46 */
  195.     HH ( c, d, a, b, in[15], S33, 530742520); /* 47 */
  196.     HH ( b, c, d, a, in[ 2], S34, 3299628645); /* 48 */
  197.     /* Round 4 */
  198. #define S41 6
  199. #define S42 10
  200. #define S43 15
  201. #define S44 21
  202.     II ( a, b, c, d, in[ 0], S41, 4096336452); /* 49 */
  203.     II ( d, a, b, c, in[ 7], S42, 1126891415); /* 50 */
  204.     II ( c, d, a, b, in[14], S43, 2878612391); /* 51 */
  205.     II ( b, c, d, a, in[ 5], S44, 4237533241); /* 52 */
  206.     II ( a, b, c, d, in[12], S41, 1700485571); /* 53 */
  207.     II ( d, a, b, c, in[ 3], S42, 2399980690); /* 54 */
  208.     II ( c, d, a, b, in[10], S43, 4293915773); /* 55 */
  209.     II ( b, c, d, a, in[ 1], S44, 2240044497); /* 56 */
  210.     II ( a, b, c, d, in[ 8], S41, 1873313359); /* 57 */
  211.     II ( d, a, b, c, in[15], S42, 4264355552); /* 58 */
  212.     II ( c, d, a, b, in[ 6], S43, 2734768916); /* 59 */
  213.     II ( b, c, d, a, in[13], S44, 1309151649); /* 60 */
  214.     II ( a, b, c, d, in[ 4], S41, 4149444226); /* 61 */
  215.     II ( d, a, b, c, in[11], S42, 3174756917); /* 62 */
  216.     II ( c, d, a, b, in[ 2], S43, 718787259); /* 63 */
  217.     II ( b, c, d, a, in[ 9], S44, 3951481745); /* 64 */
  218.     buf[0] += a;
  219.     buf[1] += b;
  220.     buf[2] += c;
  221.     buf[3] += d;
  222. }

  223. #include <stdio.h>
  224. #include <sys/types.h>
  225. #include <time.h>
  226. #include <string.h>

  227. static void MDPrint (MD5_CTX *mdContext)
  228. {
  229.         int i;
  230.         for (i = 0; i < 16; i++)
  231.         {
  232.                 printf ("%02x", mdContext->digest[i]);
  233.         }
  234. }
  235. /* size of test block */
  236. #define TEST_BLOCK_SIZE 1000
  237. /* number of blocks to process */
  238. #define TEST_BLOCKS 10000
  239. /* number of test bytes = TEST_BLOCK_SIZE * TEST_BLOCKS */
  240. static long TEST_BYTES = (long)TEST_BLOCK_SIZE * (long)TEST_BLOCKS;
  241. /* A time trial routine, to measure the speed of MD5.
  242.    Measures wall time required to digest TEST_BLOCKS * TEST_BLOCK_SIZE
  243.    characters.
  244.  */
  245. static void MDTimeTrial ()
  246. {
  247.         MD5_CTX mdContext;
  248.         time_t endTime, startTime;
  249.         unsigned char data[TEST_BLOCK_SIZE];
  250.         unsigned int i;
  251.         /* initialize test data */
  252.         for (i = 0; i < TEST_BLOCK_SIZE; i++)
  253.         {
  254.                 data[i] = (unsigned char)(i & 0xFF);
  255.         }
  256.         /* start timer */
  257.         printf ("MD5 time trial. Processing %ld characters...\n", TEST_BYTES);
  258.         time (&startTime);
  259.         /* digest data in TEST_BLOCK_SIZE byte blocks */
  260.         MD5Init (&mdContext);
  261.         for (i = TEST_BLOCKS; i > 0; i--)
  262.         {
  263.                 MD5Update (&mdContext, data, TEST_BLOCK_SIZE);
  264.         }
  265.         MD5Final (&mdContext);
  266.         /* stop timer, get time difference */
  267.         time (&endTime);
  268.         MDPrint (&mdContext);
  269.         printf (" is digest of test input.\n");
  270.         printf("Seconds to process test input: %ld\n", (long)(endTime-startTime));
  271.         printf("Characters processed per second: %ld\n",
  272.         TEST_BYTES / (endTime - startTime));
  273. }
  274. /* Computes the message digest for string inString.
  275.    Prints out message digest, a space, the string (in quotes) and a
  276.    carriage return.
  277.  */
  278. static void MDString(char *inString)
  279. {
  280.         MD5_CTX mdContext;
  281.         unsigned int len = strlen (inString);
  282.         MD5Init (&mdContext);
  283.         MD5Update (&mdContext, inString, len);
  284.         MD5Final (&mdContext);
  285.         MDPrint (&mdContext);
  286.         printf (" \"%s\"\n\n", inString);
  287. }
  288. /* Computes the message digest for a specified file.
  289.    Prints out message digest, a space, the file name, and a carriage
  290.    return.
  291.  */
  292. static void MDFile (char *filename)
  293. {
  294.         FILE *inFile = fopen (filename, "rb");
  295.         MD5_CTX mdContext;
  296.         int bytes;
  297.         unsigned char data[1024];
  298.         if (inFile == NULL)
  299.         {
  300.                 printf ("%s can't be opened.\n", filename);
  301.                 return;
  302.         }
  303.         MD5Init (&mdContext);
  304.         while ((bytes = fread (data, 1, 1024, inFile)) != 0)
  305.         {
  306.                 MD5Update (&mdContext, data, bytes);
  307.         }
  308.         MD5Final (&mdContext);
  309.         MDPrint (&mdContext);
  310.         printf (" %s\n", filename);
  311.         fclose (inFile);
  312. }
  313. /* Writes the message digest of the data from stdin onto stdout,
  314.    followed by a carriage return.
  315.  */
  316. static void MDFilter ()
  317. {
  318.         MD5_CTX mdContext;
  319.         int bytes;
  320.         unsigned char data[16];
  321.         MD5Init (&mdContext);
  322.         while ((bytes = fread (data, 1, 16, stdin)) != 0)
  323.         {
  324.                 MD5Update (&mdContext, data, bytes);
  325.         }
  326.         MD5Final (&mdContext);
  327.         MDPrint (&mdContext);
  328.         printf ("\n");
  329. }
  330. /* Runs a standard suite of test data.
  331.  */
  332. static void MDTestSuite ()
  333. {
  334.         printf ("MD5 test suite results:\n\n");
  335.         MDString ("");
  336.         MDString ("a");
  337.         MDString ("abc");
  338.         MDString ("message digest");
  339.         MDString ("abcdefghijklmnopqrstuvwxyz");
  340.         MDString("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
  341.         MDString("12345678901234567890123456789012345678901234567890123456789012345678901234567890");
  342.         /* Contents of file foo are "abc" */
  343.         MDFile ("foo");
  344. }
  345. void main (int argc, char *argv[])
  346. {
  347.         int i;
  348.         /* For each command line argument in turn:
  349.         ** filename -- prints message digest and name of file
  350.         ** -sstring -- prints message digest and contents of string 打印消息摘要和字符串内容
  351.         ** -t -- prints time trial statistics for 1M characters
  352.         ** -x -- execute a standard suite of test data
  353.         ** (no args) -- writes messages digest of stdin onto stdout
  354.         */
  355.         if (argc == 1)
  356.         {
  357.                 MDFilter ();
  358.         }
  359.         else
  360.         {
  361.                 for (i = 1; i < argc; i++)
  362.                 {
  363.                         if (argv[i][0] == '-' && argv[i][1] == 's')
  364.                                 MDString (argv[i] + 2);
  365.                         else if (strcmp (argv[i], "-t") == 0)
  366.                                 MDTimeTrial ();
  367.                         else if (strcmp (argv[i], "-x") == 0)
  368.                                 MDTestSuite ();
  369.                         else MDFile (argv[i]);
  370.                 } // end for

  371.         } // end else

  372. }
阅读(1805) | 评论(0) | 转发(0) |
0

上一篇:crc16

下一篇:弹钢琴

给主人留下些什么吧!~~