md5_hash.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:8k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. #include "md5_hash.hpp"
  14. #ifdef WORDS_BIGENDIAN
  15. #define HIGHFIRST 1
  16. #endif
  17. /*
  18.  * This code implements the MD5 message-digest algorithm.
  19.  * The algorithm is due to Ron Rivest.  This code was
  20.  * written by Colin Plumb in 1993, no copyright is claimed.
  21.  * This code is in the public domain; do with it what you wish.
  22.  *
  23.  * Equivalent code is available from RSA Data Security, Inc.
  24.  * This code has been tested against that, and is equivalent,
  25.  * except that you don't need to include two pages of legalese
  26.  * with every copy.
  27.  *
  28.  * The code has been modified by Mikael Ronstroem to handle
  29.  * calculating a hash value of a key that is always a multiple
  30.  * of 4 bytes long. Word 0 of the calculated 4-word hash value
  31.  * is returned as the hash value.
  32.  */
  33. #ifndef HIGHFIRST
  34. #define byteReverse(buf, len) /* Nothing */
  35. #else
  36. void byteReverse(unsigned char *buf, unsigned longs);
  37. /*
  38.  * Note: this code is harmless on little-endian machines.
  39.  */
  40. void byteReverse(unsigned char *buf, unsigned longs)
  41. {
  42.     Uint32 t;
  43.     do {
  44. t = (Uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
  45.     ((unsigned) buf[1] << 8 | buf[0]);
  46. *(Uint32 *) buf = t;
  47. buf += 4;
  48.     } while (--longs);
  49. }
  50. #endif
  51. /* The four core functions - F1 is optimized somewhat */
  52. /* #define F1(x, y, z) (x & y | ~x & z) */
  53. #define F1(x, y, z) (z ^ (x & (y ^ z)))
  54. #define F2(x, y, z) F1(z, x, y)
  55. #define F3(x, y, z) (x ^ y ^ z)
  56. #define F4(x, y, z) (y ^ (x | ~z))
  57. /* This is the central step in the MD5 algorithm. */
  58. #define MD5STEP(f, w, x, y, z, data, s) 
  59. ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
  60. /*
  61.  * The core of the MD5 algorithm, this alters an existing MD5 hash to
  62.  * reflect the addition of 16 longwords of new data.  MD5Update blocks
  63.  * the data and converts bytes into longwords for this routine.
  64.  */
  65. void MD5Transform(Uint32 buf[4], Uint32 const in[16])
  66. {
  67.     register Uint32 a, b, c, d;
  68.     a = buf[0];
  69.     b = buf[1];
  70.     c = buf[2];
  71.     d = buf[3];
  72.     MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
  73.     MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
  74.     MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
  75.     MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
  76.     MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
  77.     MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
  78.     MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
  79.     MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
  80.     MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
  81.     MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
  82.     MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
  83.     MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
  84.     MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
  85.     MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
  86.     MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
  87.     MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
  88.     MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
  89.     MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
  90.     MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
  91.     MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
  92.     MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
  93.     MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
  94.     MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
  95.     MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
  96.     MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
  97.     MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
  98.     MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
  99.     MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
  100.     MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
  101.     MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
  102.     MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
  103.     MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
  104.     MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
  105.     MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
  106.     MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
  107.     MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
  108.     MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
  109.     MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
  110.     MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
  111.     MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
  112.     MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
  113.     MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
  114.     MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
  115.     MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
  116.     MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
  117.     MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
  118.     MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
  119.     MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
  120.     MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
  121.     MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
  122.     MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
  123.     MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
  124.     MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
  125.     MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
  126.     MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
  127.     MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
  128.     MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
  129.     MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
  130.     MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
  131.     MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
  132.     MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
  133.     MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
  134.     MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
  135.     MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
  136.     buf[0] += a;
  137.     buf[1] += b;
  138.     buf[2] += c;
  139.     buf[3] += d;
  140. }
  141. /*
  142.  * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
  143.  * initialization constants.
  144.  */
  145. Uint32 md5_hash(const Uint64* keybuf, Uint32 no_of_32_words)
  146. {
  147. /*
  148.  * This is the external interface of the module
  149.  * It is assumed that keybuf is placed on 8 byte
  150.  * alignment.
  151.  */
  152.   Uint32 i;
  153.   Uint32 buf[4];
  154.   Uint64 transform64_buf[8];
  155.   Uint32* transform32_buf;
  156.   Uint32 len = no_of_32_words << 2;
  157.   const Uint64* key64buf = (const Uint64*)keybuf;
  158.   const Uint32* key32buf = (const Uint32*)keybuf;
  159.   transform32_buf = (Uint32*)&transform64_buf[0];
  160.   buf[0] = 0x67452301;
  161.   buf[1] = 0xefcdab89;
  162.   buf[2] = 0x98badcfe;
  163.   buf[3] = 0x10325476;
  164.   while (no_of_32_words >= 16) {
  165.     transform64_buf[0] = key64buf[0];
  166.     transform64_buf[1] = key64buf[1];
  167.     transform64_buf[2] = key64buf[2];
  168.     transform64_buf[3] = key64buf[3];
  169.     transform64_buf[4] = key64buf[4];
  170.     transform64_buf[5] = key64buf[5];
  171.     transform64_buf[6] = key64buf[6];
  172.     transform64_buf[7] = key64buf[7];
  173.     no_of_32_words -= 16;
  174.     key64buf += 8;
  175.     byteReverse((unsigned char *)transform32_buf, 16);
  176.     MD5Transform(buf, transform32_buf);
  177.   }
  178.   key32buf = (const Uint32*)key64buf;
  179.   transform64_buf[0] = 0;
  180.   transform64_buf[1] = 0;
  181.   transform64_buf[2] = 0;
  182.   transform64_buf[3] = 0;
  183.   transform64_buf[4] = 0;
  184.   transform64_buf[5] = 0;
  185.   transform64_buf[6] = 0;
  186.   transform64_buf[7] = (Uint64)len;
  187.   for (i = 0; i < no_of_32_words; i++)
  188.     transform32_buf[i] = key32buf[i];
  189.   transform32_buf[no_of_32_words] = 0x80000000;
  190.   if (no_of_32_words < 14) {
  191.     byteReverse((unsigned char *)transform32_buf, 16);
  192.     MD5Transform(buf, transform32_buf);
  193.   } else {
  194.     if (no_of_32_words == 14)
  195.       transform32_buf[15] = 0;
  196.     MD5Transform(buf, transform32_buf);
  197.     transform64_buf[0] = 0;
  198.     transform64_buf[1] = 0;
  199.     transform64_buf[2] = 0;
  200.     transform64_buf[3] = 0;
  201.     transform64_buf[4] = 0;
  202.     transform64_buf[5] = 0;
  203.     transform64_buf[6] = 0;
  204.     transform64_buf[7] = (Uint64)len;
  205.     byteReverse((unsigned char *)transform32_buf, 16);
  206.     MD5Transform(buf, transform32_buf);    
  207.   }
  208.   return buf[0];
  209. }