md5算法:MD5官方算法

Network Working Group                                          R. Rivest
Request for Comments: 1321           MIT Laboratory for Computer Science
                                             and RSA Data Security, Inc.
                                                              April 1992


                     The MD5 Message-Digest Algorithm

Status of this Memo

   This memo provides information for the Internet community.  It does
   not specy an Internet standard.  Distribution of this memo is
   unlimited.

Acknowlegements

   We would like to thank Don Coppersmith, Burt Kaliski, Ralph Merkle,
   David Chaum, and Noam Nisan for numerous helpful comments and
   suggestions.

Table of Contents

   1. Executive Summary                                                1
   2. Terminology and Notation                                         2
   3. MD5 Algorithm Description                                        3
   4. Summary                                                          6
   5. Dferences Between MD4 and MD5                                  6
   References                                                          7
   APPENDIX A - Reference Implementation                               7
   Security Considerations                                            21
   Author's Address                                                   21

1. Executive Summary

   This document describes the MD5 message-digest algorithm. The
   algorithm takes as input a message of arbitrary length and produces
   as output a 128-bit "fingerpr" or "message digest" of the input.
   It is conjectured that it is computationally infeasible to produce
   two messages having the same message digest, or to produce any
   message having a given prespecied target message digest. The MD5
   algorithm is ended for digital signature applications, where a
   large file must be "compressed" in a secure manner before being
   encrypted with a private (secret) key under a public-key cryptosystem
   such as RSA.







Rivest                                                          [Page 1]

RFC 1321              MD5 Message-Digest Algorithm            April 1992


   The MD5 algorithm is designed to be quite fast _disibledevent=>      iso(1) member-body(2) US(840) rsadsi(113549) digestAlgorithm(2) 5}

   In the X.509 type AlgorithmIdentier [3], the parameters for MD5
   should have type NULL.

2. Terminology and Notation

   In this document a "word" is a 32-bit quantity and a "" is an
   eight-bit quantity. A sequence of bits can be erpreted in a
   natural manner as a sequence of s, where each consecutive group
   of eight bits is erpreted as a with the high-order (most
   signicant) bit of each listed first. Similarly, a sequence of
   s can be erpreted as a sequence of 32-bit words, where each
   consecutive group of four s is erpreted as a word with the
   low-order (least signicant) given first.

   Let x_i denote "x sub i". If the subscript is an expression, we
   surround it in braces, as in x_{i+1}. Similarly, we use ^ for
   superscripts (exponentiation), so that x^i denotes x to the i-th
   power.

   Let the symbol "+" denote addition of words (i.e., modulo-2^32
   addition). Let X <<< s denote the 32-bit value obtained by circularly
   shting (rotating) X left by s bit positions. Let not(X) denote the
   bit-wise complement of X, and let X v Y denote the bit-wise OR of X
   and Y. Let X xor Y denote the bit-wise XOR of X and Y, and let XY
   denote the bit-wise AND of X and Y.





Rivest                                                          [Page 2]

RFC 1321              MD5 Message-Digest Algorithm            April 1992


3. MD5 Algorithm Description

   We begin by supposing that we have a b-bit message as input, and that
   we wish to find its message digest. Here b is an arbitrary
   nonnegative eger; b may be zero, it need not be a multiple of
   eight, and it may be arbitrarily large. We imagine the bits of the
   message written down as follows:

          m_0 m_1 ... m_{b-1}

   The following five steps are performed to compute the message digest
   of the message.

3.1 Step 1. Append Padding Bits

   The message is "padded" (extended) so that its length (in bits) is
   congruent to 448, modulo 512. That is, the message is extended so
   that it is just 64 bits shy of being a multiple of 512 bits long.
   Padding is always performed, even the length of the message is
   already congruent to 448, modulo 512.

   Padding is performed as follows: a single "1" bit is appended to the
   message, and then "0" bits are appended so that the length in bits of
   the padded message becomes congruent to 448, modulo 512. In all, at
   least _disibledevent=>           G(X,Y,Z) = XZ v Y not(Z)
          H(X,Y,Z) = X xor Y xor Z
          I(X,Y,Z) = Y xor (X v not(Z))

   In each bit position F acts as a conditional: X then Y Z.
   The function F could have been d using + instead of v since XY
   and not(X)Z will never have 1's in the same bit position.) It is
   eresting to note that the bits of X, Y, and Z are independent
   and unbiased, the each bit of F(X,Y,Z) will be independent and
   unbiased.

   The functions G, H, and I are similar to the function F, in that they
   act in "bitwise parallel" to produce their output from the bits of X,
   Y, and Z, in such a manner that the corresponding bits of X, Y,
   and Z are independent and unbiased, then each bit of G(X,Y,Z),
   H(X,Y,Z), and I(X,Y,Z) will be independent and unbiased. Note that
   the function H is the bit-wise "xor" or "parity" function of its
   inputs.

   This step uses a 64-element table T[1 ... 64] constructed from the
   sine function. Let T[i] denote the i-th element of the table, which
   is equal to the eger part of 4294967296 times abs(sin(i)), where i
   is in radians. The elements of the table are given in the appendix.

   Do the following:

   /* Process each 16-word block. */
   For i = 0 to N/16-1 do

     /* Copy block i o X. */
     For j = 0 to 15 do
       Set X[j] to M[i*16+j].
     end /* of loop _disibledevent=>      BB = B



Rivest                                                          [Page 4]

RFC 1321              MD5 Message-Digest Algorithm            April 1992


     CC = C
     DD = D

     /* Round 1. */
     /* Let [abcd k s i] denote the operation
          a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
     /* Do the following 16 operations. */
     [ABCD  0  7  1]  [DABC  1 12  2]  [CDAB  2 17  3]  [BCDA  3 22  4]
     [ABCD  4  7  5]  [DABC  5 12  6]  [CDAB  6 17  7]  [BCDA  7 22  8]
     [ABCD  8  7  9]  [DABC  9 12 10]  [CDAB 10 17 11]  [BCDA 11 22 12]
     [ABCD 12  7 13]  [DABC 13 12 14]  [CDAB 14 17 15]  [BCDA 15 22 16]

     /* Round 2. */
     /* Let [abcd k s i] denote the operation
          a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
     /* Do the following 16 operations. */
     [ABCD  1  5 17]  [DABC  6  9 18]  [CDAB 11 14 19]  [BCDA  0 20 20]
     [ABCD  5  5 21]  [DABC 10  9 22]  [CDAB 15 14 23]  [BCDA  4 20 24]
     [ABCD  9  5 25]  [DABC 14  9 26]  [CDAB  3 14 27]  [BCDA  8 20 28]
     [ABCD 13  5 29]  [DABC  2  9 30]  [CDAB  7 14 31]  [BCDA 12 20 32]

     /* Round 3. */
     /* Let [abcd k s t] denote the operation
          a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
     /* Do the following 16 operations. */
     [ABCD  5  4 33]  [DABC  8 11 34]  [CDAB 11 16 35]  [BCDA 14 23 36]
     [ABCD  1  4 37]  [DABC  4 11 38]  [CDAB  7 16 39]  [BCDA 10 23 40]
     [ABCD 13  4 41]  [DABC  0 11 42]  [CDAB  3 16 43]  [BCDA  6 23 44]
     [ABCD  9  4 45]  [DABC 12 11 46]  [CDAB 15 16 47]  [BCDA  2 23 48]

     /* Round 4. */
     /* Let [abcd k s t] denote the operation
          a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
     /* Do the following 16 operations. */
     [ABCD  0  6 49]  [DABC  7 10 50]  [CDAB 14 15 51]  [BCDA  5 21 52]
     [ABCD 12  6 53]  [DABC  3 10 54]  [CDAB 10 15 55]  [BCDA  1 21 56]
     [ABCD  8  6 57]  [DABC 15 10 58]  [CDAB  6 15 59]  [BCDA 13 21 60]
     [ABCD  4  6 61]  [DABC 11 10 62]  [CDAB  2 15 63]  [BCDA  9 21 64]

     /* Then perform the following additions. (That is increment each
        of the four registers by the value it had before this block
        was started.) */
     A = A + AA
     B = B + BB
     C = C + CC
     D = D + DD

   end /* of loop _disibledevent=>   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
};

/* F, G, H and I are basic MD5 functions.
*/
# F(x, y, z) (((x) & (y)) | ((~x) & (z)))
# G(x, y, z) (((x) & (z)) | ((y) & (~z)))
# H(x, y, z) ((x) ^ (y) ^ (z))
# I(x, y, z) ((y) ^ ((x) | (~z)))

/* ROTATE_LEFT rotates x left n bits.
*/
# ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))

/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
Rotation is separate from addition to prevent recomputation.
*/
# FF(a, b, c, d, x, s, ac) { \
(a) F ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \



Rivest                                                         [Page 10]

RFC 1321              MD5 Message-Digest Algorithm            April 1992


(a) (b); \
  }
# GG(a, b, c, d, x, s, ac) { \
(a) G ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) (b); \
  }
# HH(a, b, c, d, x, s, ac) { \
(a) H ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) (b); \
  }
# II(a, b, c, d, x, s, ac) { \
(a) I ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) (b); \
  }

/* MD5 initialization. Begins an MD5 operation, writing a context.
*/
void MD5Init (context)
MD5_CTX *context;                                        /* context */
{
  context->count[0] = context->count[1] = 0;
  /* Load magic initialization constants.
*/
  context->state[0] = 0x67452301;
  context->state[1] = 0xefcdab89;
  context->state[2] = 0x98badcfe;
  context->state[3] = 0x10325476;
}

/* MD5 block update operation. Continues an MD5 message-digest
  operation, processing another message block, and updating the
  context.
*/
void MD5Update (context, input, inputLen)
MD5_CTX *context;                                        /* context */
unsigned char *input;                                /* input block */
unsigned inputLen;                     /* length of input block */
{
  unsigned i, index, partLen;

  /* Compute number of s mod 64 */
  index = (unsigned )((context->count[0] >> 3) & 0x3F);

  /* Update number of bits */
   ((context->count[0] ((UINT4)inputLen << 3))



Rivest                                                         [Page 11]

RFC 1321              MD5 Message-Digest Algorithm            April 1992


   < ((UINT4)inputLen << 3))
context->count[1];
  context->count[1] ((UINT4)inputLen >> 29);

  partLen = 64 - index;

  /* Transform as many times as possible.
*/
   (inputLen >= partLen) {
MD5_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;
  }
  
i = 0;

  /* Buffer reing input */
  MD5_memcpy
((POINTER)&context->buffer[index], (POINTER)&input[i],
  inputLen-i);
}

/* MD5 finalization. Ends an MD5 message-digest operation, writing the
  the message digest and zeroizing the context.
*/
void MD5Final (digest, context)
unsigned char digest[16];                         /* message digest */
MD5_CTX *context;                                       /* context */
{
  unsigned char bits[8];
  unsigned index, padLen;

  /* Save number of bits */
  Encode (bits, context->count, 8);

  /* Pad out to 56 mod 64.
*/
  index = (unsigned )((context->count[0] >> 3) & 0x3f);
  padLen = (index < 56) ? (56 - index) : (120 - index);
  MD5Update (context, PADDING, padLen);

  /* Append length (before padding) */
  MD5Update (context, bits, 8);



Rivest                                                         [Page 12]

RFC 1321              MD5 Message-Digest Algorithm            April 1992


  /* Store state in digest */
  Encode (digest, context->state, 16);

  /* Zeroize sensitive information.
*/
  MD5_mem ((POINTER)context, 0, (*context));
}

/* MD5 basic transformation. Transforms state based _disibledevent=>
  Decode (x, block, 64);

  /* Round 1 */
  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 */

/* Round 2 */
  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 */



Rivest                                                         [Page 13]

RFC 1321              MD5 Message-Digest Algorithm            April 1992


  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 */

  /* Round 3 */
  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 */

  /* Round 4 */
  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;

  /* Zeroize sensitive information.



Rivest                                                         [Page 14]

RFC 1321              MD5 Message-Digest Algorithm            April 1992


*/
  MD5_mem ((POINTER)x, 0, (x));
}

/* Encodes input (UINT4) o output (unsigned char). Assumes len is
  a multiple of 4.
*/
void Encode (output, input, len)
unsigned char *output;
UINT4 *input;
unsigned len;
{
  unsigned 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);
  }
}

/* Decodes input (unsigned char) o output (UINT4). Assumes len is
  a multiple of 4.
*/
void Decode (output, input, len)
UINT4 *output;
unsigned char *input;
unsigned len;
{
  unsigned 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);
}

/* Note: Replace "for loop" with standard memcpy possible.
*/

void MD5_memcpy (output, input, len)
POINTER output;
POINTER input;
unsigned len;
{
  unsigned i;

  for (i = 0; i < len; i)



Rivest                                                         [Page 15]

RFC 1321              MD5 Message-Digest Algorithm            April 1992


output[i] = input[i];
}

/* Note: Replace "for loop" with standard mem possible.
*/
void MD5_mem (output, value, len)
POINTER output;
value;
unsigned len;
{
  unsigned i;

  for (i = 0; i < len; i)
((char *)output)[i] = (char)value;
}

A.4 mddriver.c

/* MDDRIVER.C - test driver for MD2, MD4 and MD5
*/

/* Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
rights reserved.

RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.

These notices must be retained in any copies of any part of this
documentation and/or software.
*/

/* The following makes MD default to MD5 it has not already been
  d with C compiler flags.
*/
#ndef MD
# MD MD5
#end

# <stdio.h>
# <time.h>
# <.h>
# "global.h"
# MD 2
# "md2.h"
#end
# MD 4



Rivest                                                         [Page 16]

RFC 1321              MD5 Message-Digest Algorithm            April 1992


# "md4.h"
#end
# MD 5
# "md5.h"
#end

/* Length of test block, number of test blocks.
*/
# TEST_BLOCK_LEN 1000
# TEST_BLOCK_COUNT 1000

void MDString PROTO_LIST ((char *));
void MDTimeTrial PROTO_LIST ((void));
void MDTestSuite PROTO_LIST ((void));
void MDFile PROTO_LIST ((char *));
void MDFilter PROTO_LIST ((void));
void MDPr PROTO_LIST ((unsigned char [16]));

# MD 2
# MD_CTX MD2_CTX
# MDInit MD2Init
# MDUpdate MD2Update
# MDFinal MD2Final
#end
# MD 4
# MD_CTX MD4_CTX
# MDInit MD4Init
# MDUpdate MD4Update
# MDFinal MD4Final
#end
# MD 5
# MD_CTX MD5_CTX
# MDInit MD5Init
# MDUpdate MD5Update
# MDFinal MD5Final
#end

/* Main driver.

Arguments (may be any combination):
  -s - digests
  -t       - runs time trial
  -x       - runs test script
  filename - digests file
  (none)   - digests standard input
*/
(argc, argv)
argc;



Rivest                                                         [Page 17]

RFC 1321              MD5 Message-Digest Algorithm            April 1992


char *argv;
{
   i;

   (argc > 1)
for (i = 1; i < argc; i)
    (argv[i][0] '-' && argv[i][1] 's')
     MDString (argv[i] + 2);
    (strcmp (argv[i], "-t") 0)
     MDTimeTrial ;
    (strcmp (argv[i], "-x") 0)
     MDTestSuite ;
   
     MDFile (argv[i]);
  
MDFilter ;

   (0);
}

/* Digests a and prs the result.
*/
void MDString ()
char *;
{
  MD_CTX context;
  unsigned char digest[16];
  unsigned len = strlen ();

  MDInit (&context);
  MDUpdate (&context, , len);
  MDFinal (digest, &context);

  prf ("MD%d (\"%s\") = ", MD, );
  MDPr (digest);
  prf ("\n");
}

/* Measures the time to digest TEST_BLOCK_COUNT TEST_BLOCK_LEN-
  blocks.
*/
void MDTimeTrial
{
  MD_CTX context;
  time_t endTime, startTime;
  unsigned char block[TEST_BLOCK_LEN], digest[16];
  unsigned i;




Rivest                                                         [Page 18]

RFC 1321              MD5 Message-Digest Algorithm            April 1992


  prf
("MD%d time trial. Digesting %d %d- blocks ...", MD,
  TEST_BLOCK_LEN, TEST_BLOCK_COUNT);

  /* Initialize block */
  for (i = 0; i < TEST_BLOCK_LEN; i)
block[i] = (unsigned char)(i & 0xff);

  /* Start timer */
  time (&startTime);

  /* Digest blocks */
  MDInit (&context);
  for (i = 0; i < TEST_BLOCK_COUNT; i)
MDUpdate (&context, block, TEST_BLOCK_LEN);
  MDFinal (digest, &context);

  /* Stop timer */
  time (&endTime);

  prf (" done\n");
  prf ("Digest = ");
  MDPr (digest);
  prf ("\nTime = %ld seconds\n", (long)(endTime-startTime));
  prf
("Speed = %ld s/second\n",
  (long)TEST_BLOCK_LEN * (long)TEST_BLOCK_COUNT/(endTime-startTime));
}

/* Digests a reference suite of s and prs the results.
*/
void MDTestSuite
{
  prf ("MD%d test suite:\n", MD);

  MDString ("");
  MDString ("a");
  MDString ("abc");
  MDString ("message digest");
  MDString ("abcdefghijklmnopqrstuvwxyz");
  MDString
("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
  MDString
("1234567890123456789012345678901234567890\
1234567890123456789012345678901234567890");
}

/* Digests a file and prs the result.



Rivest                                                         [Page 19]

RFC 1321              MD5 Message-Digest Algorithm            April 1992


*/
void MDFile (filename)
char *filename;
{
  FILE *file;
  MD_CTX context;
   len;
  unsigned char buffer[1024], digest[16];

   ((file = fopen (filename, "rb")) NULL)
prf ("%s can't be opened\n", filename);

   {
MDInit (&context);
while (len = fread (buffer, 1, 1024, file))
   MDUpdate (&context, buffer, len);
MDFinal (digest, &context);

fclose (file);

prf ("MD%d (%s) = ", MD, filename);
MDPr (digest);
prf ("\n");
  }
}

/* Digests the standard input and prs the result.
*/
void MDFilter
{
  MD_CTX context;
   len;
  unsigned char buffer[16], digest[16];

  MDInit (&context);
  while (len = fread (buffer, 1, 16, stdin))
MDUpdate (&context, buffer, len);
  MDFinal (digest, &context);

  MDPr (digest);
  prf ("\n");
}

/* Prs a message digest in hexadecimal.
*/
void MDPr (digest)
unsigned char digest[16];
{



Rivest                                                         [Page 20]

RFC 1321              MD5 Message-Digest Algorithm            April 1992


  unsigned i;

  for (i = 0; i < 16; i)
prf ("%02x", digest[i]);
}

A.5 Test suite

   The MD5 test suite (driver option "-x") should pr the following
   results:

MD5 test suite:
MD5 ("") = d41d8cd98f00b204e9800998ecf8427e
MD5 ("a") = 0cc175b9c0f1b6a831c399e269772661
MD5 ("abc") = 900150983cd24fb0d6963f7d28e17f72
MD5 ("message digest") = f96b697d7cb7938d525a2f31aaf161d0
MD5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b
MD5 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") =
d174ab98d277d9f5a5611c2c9f419d9f
MD5 ("123456789012345678901234567890123456789012345678901234567890123456
78901234567890") = 57edf4a22be3c955ac49da2e2107b67a

Security Considerations

   The level of security discussed in this memo is considered to be
   sufficient for implementing very high security hybrid digital-
   signature schemes based _disibledevent=>


  • 篇文章: IBM、SUN等公司Java面试题集

  • 篇文章: VC 下TabCtrl键控制问题解决办法
  • Tags:  md5算法原理 md5解密算法 md5加密算法 md5算法

    延伸阅读

    最新评论

    发表评论