md5.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:10k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * md5.c: not so strong MD5 hashing
  3.  *****************************************************************************
  4.  * Copyright (C) 2004-2005 the VideoLAN team
  5.  * $Id: f4f93fff818bfdfb1e7c1c35d86fb6d1fa735494 $
  6.  *
  7.  * Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
  8.  *          Sam Hocevar <sam@zoy.org>
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2 of the License, or
  13.  * (at your option) any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to the Free Software
  22.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  23.  *****************************************************************************/
  24. #ifdef HAVE_CONFIG_H
  25. # include "config.h"
  26. #endif
  27. #include <string.h>
  28. #include <vlc_common.h>
  29. #include <vlc_md5.h>
  30. #ifdef WORDS_BIGENDIAN
  31. /*****************************************************************************
  32.  * Reverse: reverse byte order
  33.  *****************************************************************************/
  34. static inline void Reverse( uint32_t *p_buffer, int n )
  35. {
  36.     int i;
  37.     for( i = 0; i < n; i++ )
  38.     {
  39.         p_buffer[ i ] = GetDWLE(&p_buffer[ i ]);
  40.     }
  41. }
  42. #    define REVERSE( p, n ) Reverse( p, n )
  43. #else
  44. #    define REVERSE( p, n )
  45. #endif
  46. #define F1( x, y, z ) ((z) ^ ((x) & ((y) ^ (z))))
  47. #define F2( x, y, z ) F1((z), (x), (y))
  48. #define F3( x, y, z ) ((x) ^ (y) ^ (z))
  49. #define F4( x, y, z ) ((y) ^ ((x) | ~(z)))
  50. #define MD5_DO( f, w, x, y, z, data, s ) 
  51.     ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
  52. /*****************************************************************************
  53.  * DigestMD5: update the MD5 digest with 64 bytes of data
  54.  *****************************************************************************/
  55. static void DigestMD5( struct md5_s *p_md5, uint32_t *p_input )
  56. {
  57.     uint32_t a, b, c, d;
  58.     REVERSE( p_input, 16 );
  59.     a = p_md5->p_digest[ 0 ];
  60.     b = p_md5->p_digest[ 1 ];
  61.     c = p_md5->p_digest[ 2 ];
  62.     d = p_md5->p_digest[ 3 ];
  63.     MD5_DO( F1, a, b, c, d, p_input[  0 ] + 0xd76aa478,  7 );
  64.     MD5_DO( F1, d, a, b, c, p_input[  1 ] + 0xe8c7b756, 12 );
  65.     MD5_DO( F1, c, d, a, b, p_input[  2 ] + 0x242070db, 17 );
  66.     MD5_DO( F1, b, c, d, a, p_input[  3 ] + 0xc1bdceee, 22 );
  67.     MD5_DO( F1, a, b, c, d, p_input[  4 ] + 0xf57c0faf,  7 );
  68.     MD5_DO( F1, d, a, b, c, p_input[  5 ] + 0x4787c62a, 12 );
  69.     MD5_DO( F1, c, d, a, b, p_input[  6 ] + 0xa8304613, 17 );
  70.     MD5_DO( F1, b, c, d, a, p_input[  7 ] + 0xfd469501, 22 );
  71.     MD5_DO( F1, a, b, c, d, p_input[  8 ] + 0x698098d8,  7 );
  72.     MD5_DO( F1, d, a, b, c, p_input[  9 ] + 0x8b44f7af, 12 );
  73.     MD5_DO( F1, c, d, a, b, p_input[ 10 ] + 0xffff5bb1, 17 );
  74.     MD5_DO( F1, b, c, d, a, p_input[ 11 ] + 0x895cd7be, 22 );
  75.     MD5_DO( F1, a, b, c, d, p_input[ 12 ] + 0x6b901122,  7 );
  76.     MD5_DO( F1, d, a, b, c, p_input[ 13 ] + 0xfd987193, 12 );
  77.     MD5_DO( F1, c, d, a, b, p_input[ 14 ] + 0xa679438e, 17 );
  78.     MD5_DO( F1, b, c, d, a, p_input[ 15 ] + 0x49b40821, 22 );
  79.     MD5_DO( F2, a, b, c, d, p_input[  1 ] + 0xf61e2562,  5 );
  80.     MD5_DO( F2, d, a, b, c, p_input[  6 ] + 0xc040b340,  9 );
  81.     MD5_DO( F2, c, d, a, b, p_input[ 11 ] + 0x265e5a51, 14 );
  82.     MD5_DO( F2, b, c, d, a, p_input[  0 ] + 0xe9b6c7aa, 20 );
  83.     MD5_DO( F2, a, b, c, d, p_input[  5 ] + 0xd62f105d,  5 );
  84.     MD5_DO( F2, d, a, b, c, p_input[ 10 ] + 0x02441453,  9 );
  85.     MD5_DO( F2, c, d, a, b, p_input[ 15 ] + 0xd8a1e681, 14 );
  86.     MD5_DO( F2, b, c, d, a, p_input[  4 ] + 0xe7d3fbc8, 20 );
  87.     MD5_DO( F2, a, b, c, d, p_input[  9 ] + 0x21e1cde6,  5 );
  88.     MD5_DO( F2, d, a, b, c, p_input[ 14 ] + 0xc33707d6,  9 );
  89.     MD5_DO( F2, c, d, a, b, p_input[  3 ] + 0xf4d50d87, 14 );
  90.     MD5_DO( F2, b, c, d, a, p_input[  8 ] + 0x455a14ed, 20 );
  91.     MD5_DO( F2, a, b, c, d, p_input[ 13 ] + 0xa9e3e905,  5 );
  92.     MD5_DO( F2, d, a, b, c, p_input[  2 ] + 0xfcefa3f8,  9 );
  93.     MD5_DO( F2, c, d, a, b, p_input[  7 ] + 0x676f02d9, 14 );
  94.     MD5_DO( F2, b, c, d, a, p_input[ 12 ] + 0x8d2a4c8a, 20 );
  95.     MD5_DO( F3, a, b, c, d, p_input[  5 ] + 0xfffa3942,  4 );
  96.     MD5_DO( F3, d, a, b, c, p_input[  8 ] + 0x8771f681, 11 );
  97.     MD5_DO( F3, c, d, a, b, p_input[ 11 ] + 0x6d9d6122, 16 );
  98.     MD5_DO( F3, b, c, d, a, p_input[ 14 ] + 0xfde5380c, 23 );
  99.     MD5_DO( F3, a, b, c, d, p_input[  1 ] + 0xa4beea44,  4 );
  100.     MD5_DO( F3, d, a, b, c, p_input[  4 ] + 0x4bdecfa9, 11 );
  101.     MD5_DO( F3, c, d, a, b, p_input[  7 ] + 0xf6bb4b60, 16 );
  102.     MD5_DO( F3, b, c, d, a, p_input[ 10 ] + 0xbebfbc70, 23 );
  103.     MD5_DO( F3, a, b, c, d, p_input[ 13 ] + 0x289b7ec6,  4 );
  104.     MD5_DO( F3, d, a, b, c, p_input[  0 ] + 0xeaa127fa, 11 );
  105.     MD5_DO( F3, c, d, a, b, p_input[  3 ] + 0xd4ef3085, 16 );
  106.     MD5_DO( F3, b, c, d, a, p_input[  6 ] + 0x04881d05, 23 );
  107.     MD5_DO( F3, a, b, c, d, p_input[  9 ] + 0xd9d4d039,  4 );
  108.     MD5_DO( F3, d, a, b, c, p_input[ 12 ] + 0xe6db99e5, 11 );
  109.     MD5_DO( F3, c, d, a, b, p_input[ 15 ] + 0x1fa27cf8, 16 );
  110.     MD5_DO( F3, b, c, d, a, p_input[  2 ] + 0xc4ac5665, 23 );
  111.     MD5_DO( F4, a, b, c, d, p_input[  0 ] + 0xf4292244,  6 );
  112.     MD5_DO( F4, d, a, b, c, p_input[  7 ] + 0x432aff97, 10 );
  113.     MD5_DO( F4, c, d, a, b, p_input[ 14 ] + 0xab9423a7, 15 );
  114.     MD5_DO( F4, b, c, d, a, p_input[  5 ] + 0xfc93a039, 21 );
  115.     MD5_DO( F4, a, b, c, d, p_input[ 12 ] + 0x655b59c3,  6 );
  116.     MD5_DO( F4, d, a, b, c, p_input[  3 ] + 0x8f0ccc92, 10 );
  117.     MD5_DO( F4, c, d, a, b, p_input[ 10 ] + 0xffeff47d, 15 );
  118.     MD5_DO( F4, b, c, d, a, p_input[  1 ] + 0x85845dd1, 21 );
  119.     MD5_DO( F4, a, b, c, d, p_input[  8 ] + 0x6fa87e4f,  6 );
  120.     MD5_DO( F4, d, a, b, c, p_input[ 15 ] + 0xfe2ce6e0, 10 );
  121.     MD5_DO( F4, c, d, a, b, p_input[  6 ] + 0xa3014314, 15 );
  122.     MD5_DO( F4, b, c, d, a, p_input[ 13 ] + 0x4e0811a1, 21 );
  123.     MD5_DO( F4, a, b, c, d, p_input[  4 ] + 0xf7537e82,  6 );
  124.     MD5_DO( F4, d, a, b, c, p_input[ 11 ] + 0xbd3af235, 10 );
  125.     MD5_DO( F4, c, d, a, b, p_input[  2 ] + 0x2ad7d2bb, 15 );
  126.     MD5_DO( F4, b, c, d, a, p_input[  9 ] + 0xeb86d391, 21 );
  127.     p_md5->p_digest[ 0 ] += a;
  128.     p_md5->p_digest[ 1 ] += b;
  129.     p_md5->p_digest[ 2 ] += c;
  130.     p_md5->p_digest[ 3 ] += d;
  131. }
  132. /*****************************************************************************
  133.  * InitMD5: initialise an MD5 message
  134.  *****************************************************************************
  135.  * The MD5 message-digest algorithm is described in RFC 1321
  136.  *****************************************************************************/
  137. void InitMD5( struct md5_s *p_md5 )
  138. {
  139.     p_md5->p_digest[ 0 ] = 0x67452301;
  140.     p_md5->p_digest[ 1 ] = 0xefcdab89;
  141.     p_md5->p_digest[ 2 ] = 0x98badcfe;
  142.     p_md5->p_digest[ 3 ] = 0x10325476;
  143.     memset( p_md5->p_data, 0, 64 );
  144.     p_md5->i_bits = 0;
  145. }
  146. /*****************************************************************************
  147.  * AddMD5: add i_len bytes to an MD5 message
  148.  *****************************************************************************/
  149. void AddMD5( struct md5_s *p_md5, const void *p_src, size_t i_len )
  150. {
  151.     unsigned int i_current; /* Current bytes in the spare buffer */
  152.     size_t i_offset = 0;
  153.     i_current = (p_md5->i_bits / 8) & 63;
  154.     p_md5->i_bits += 8 * i_len;
  155.     /* If we can complete our spare buffer to 64 bytes, do it and add the
  156.      * resulting buffer to the MD5 message */
  157.     if( i_len >= (64 - i_current) )
  158.     {
  159.         memcpy( ((uint8_t *)p_md5->p_data) + i_current, p_src,
  160.                 (64 - i_current) );
  161.         DigestMD5( p_md5, p_md5->p_data );
  162.         i_offset += (64 - i_current);
  163.         i_len -= (64 - i_current);
  164.         i_current = 0;
  165.     }
  166.     /* Add as many entire 64 bytes blocks as we can to the MD5 message */
  167.     while( i_len >= 64 )
  168.     {
  169.         uint32_t p_tmp[ 16 ];
  170.         memcpy( p_tmp, ((const uint8_t *)p_src) + i_offset, 64 );
  171.         DigestMD5( p_md5, p_tmp );
  172.         i_offset += 64;
  173.         i_len -= 64;
  174.     }
  175.     /* Copy our remaining data to the message's spare buffer */
  176.     memcpy( ((uint8_t *)p_md5->p_data) + i_current,
  177.             ((const uint8_t *)p_src) + i_offset, i_len );
  178. }
  179. /*****************************************************************************
  180.  * EndMD5: finish an MD5 message
  181.  *****************************************************************************
  182.  * This function adds adequate padding to the end of the message, and appends
  183.  * the bit count so that we end at a block boundary.
  184.  *****************************************************************************/
  185. void EndMD5( struct md5_s *p_md5 )
  186. {
  187.     unsigned int i_current;
  188.     i_current = (p_md5->i_bits / 8) & 63;
  189.     /* Append 0x80 to our buffer. No boundary check because the temporary
  190.      * buffer cannot be full, otherwise AddMD5 would have emptied it. */
  191.     ((uint8_t *)p_md5->p_data)[ i_current++ ] = 0x80;
  192.     /* If less than 8 bytes are available at the end of the block, complete
  193.      * this 64 bytes block with zeros and add it to the message. We'll add
  194.      * our length at the end of the next block. */
  195.     if( i_current > 56 )
  196.     {
  197.         memset( ((uint8_t *)p_md5->p_data) + i_current, 0, (64 - i_current) );
  198.         DigestMD5( p_md5, p_md5->p_data );
  199.         i_current = 0;
  200.     }
  201.     /* Fill the unused space in our last block with zeroes and put the
  202.      * message length at the end. */
  203.     memset( ((uint8_t *)p_md5->p_data) + i_current, 0, (56 - i_current) );
  204.     p_md5->p_data[ 14 ] = p_md5->i_bits & 0xffffffff;
  205.     p_md5->p_data[ 15 ] = (p_md5->i_bits >> 32);
  206.     REVERSE( &p_md5->p_data[ 14 ], 2 );
  207.     DigestMD5( p_md5, p_md5->p_data );
  208. }