MD5 Algorithm

MD5 is a widely used cryptographic hash function with a 128-bit hash value. Usually passwords are not stored directly in file or database, the MD5 hash code is stored. Then compute hash code of inputted password and compare it to previously stored value. You use the following code to compute MD5 hash code:

ExpandedBlockStart.gif Code
     static   string  GetMd5Hash( string  input)
    {
        
byte [] data  =  Encoding.UTF8.GetBytes(input);

        System.Security.Cryptography.MD5 md5 
=   new  System.Security.Cryptography.MD5CryptoServiceProvider();
        
byte [] hash  =  md5.ComputeHash(data);

        StringBuilder sBuilder 
=   new  StringBuilder();
        
for  ( int  i  =   0 ; i  <  hash.Length; i ++ )
        {
            sBuilder.Append(hash[i].ToString(
" x2 " ));
        }
        
return  sBuilder.ToString();
    }

 

 

If you want to know how the algorithm works, you can look the code below:

 

ExpandedBlockStart.gif The code
     ///   <summary>
    
///  MD5 Alogrithm
    
///   </summary>
     public   class  MD5
    {
        
// static state variables
         private   static  UInt32 A;
        
private   static  UInt32 B;
        
private   static  UInt32 C;
        
private   static  UInt32 D;

        
// number of bits to rotate in tranforming
         private   const   int  S11  =   7 ;
        
private   const   int  S12  =   12 ;
        
private   const   int  S13  =   17 ;
        
private   const   int  S14  =   22 ;
        
private   const   int  S21  =   5 ;
        
private   const   int  S22  =   9 ;
        
private   const   int  S23  =   14 ;
        
private   const   int  S24  =   20 ;
        
private   const   int  S31  =   4 ;
        
private   const   int  S32  =   11 ;
        
private   const   int  S33  =   16 ;
        
private   const   int  S34  =   23 ;
        
private   const   int  S41  =   6 ;
        
private   const   int  S42  =   10 ;
        
private   const   int  S43  =   15 ;
        
private   const   int  S44  =   21 ;


        
/*  F, G, H and I are basic nonlinear 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))
         * 
         *  & and, | or, ~ not, ^ xor
         
*/
        
///   <summary>
        
///  Fs the specified x.
        
///   </summary>
        
///   <param name="x"> The x. </param>
        
///   <param name="y"> The y. </param>
        
///   <param name="z"> The z. </param>
        
///   <returns></returns>
         private   static  UInt32 F(UInt32 x, UInt32 y, UInt32 z)
        {
            
return  (x  &  y)  |  (( ~ x)  &  z);
        }
        
///   <summary>
        
///  Gs the specified x.
        
///   </summary>
        
///   <param name="x"> The x. </param>
        
///   <param name="y"> The y. </param>
        
///   <param name="z"> The z. </param>
        
///   <returns></returns>
         private   static  UInt32 G(UInt32 x, UInt32 y, UInt32 z)
        {
            
return  (x  &  z)  |  (y  &  ( ~ z));
        }
        
///   <summary>
        
///  Hs the specified x.
        
///   </summary>
        
///   <param name="x"> The x. </param>
        
///   <param name="y"> The y. </param>
        
///   <param name="z"> The z. </param>
        
///   <returns></returns>
         private   static  UInt32 H(UInt32 x, UInt32 y, UInt32 z)
        {
            
return  x  ^  y  ^  z;
        }
        
///   <summary>
        
///  Is the specified x.
        
///   </summary>
        
///   <param name="x"> The x. </param>
        
///   <param name="y"> The y. </param>
        
///   <param name="z"> The z. </param>
        
///   <returns></returns>
         private   static  UInt32 I(UInt32 x, UInt32 y, UInt32 z)
        {
            
return  y  ^  (x  |  ( ~ z));
        }

        
/*  FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
         * Rotation is separate from addition to prevent recomputation.
         
*/
        
private   static   void  FF( ref  UInt32 a, UInt32 b, UInt32 c, UInt32 d, UInt32 mj,  int  s, UInt32 ti)
        {
            a 
=  a  +  F(b, c, d)  +  mj  +  ti;
            a 
=  a  <<  s  |  a  >>  ( 32   -  s);
            a 
+=  b;
        }
        
private   static   void  GG( ref  UInt32 a, UInt32 b, UInt32 c, UInt32 d, UInt32 mj,  int  s, UInt32 ti)
        {
            a 
=  a  +  G(b, c, d)  +  mj  +  ti;
            a 
=  a  <<  s  |  a  >>  ( 32   -  s);
            a 
+=  b;
        }
        
private   static   void  HH( ref  UInt32 a, UInt32 b, UInt32 c, UInt32 d, UInt32 mj,  int  s, UInt32 ti)
        {
            a 
=  a  +  H(b, c, d)  +  mj  +  ti;
            a 
=  a  <<  s  |  a  >>  ( 32   -  s);
            a 
+=  b;
        }
        
private   static   void  II( ref  UInt32 a, UInt32 b, UInt32 c, UInt32 d, UInt32 mj,  int  s, UInt32 ti)
        {
            a 
=  a  +  I(b, c, d)  +  mj  +  ti;
            a 
=  a  <<  s  |  a  >>  ( 32   -  s);
            a 
+=  b;
        }

        
private   static   void  MD5_Init()
        {
            A 
=   0x67452301 ;   // in memory, this is 0x01234567
            B  =   0xefcdab89 ;   // in memory, this is 0x89abcdef
            C  =   0x98badcfe ;   // in memory, this is 0xfedcba98
            D  =   0x10325476 ;   // in memory, this is 0x76543210
        }

        
private   static  UInt32[] MD5_Append( byte [] input)
        {
            
int  zeros  =   0 ;
            
int  ones  =   1 ;
            
int  size  =   0 ;
            
int  n  =  input.Length;
            
int  m  =  n  %   64 ;
            
if  (m  <   56 )
            {
                zeros 
=   55   -  m;
                size 
=  n  -  m  +   64 ;
            }
            
else   if  (m  ==   56 )
            {
                zeros 
=   0 ;
                ones 
=   0 ;
                size 
=  n  +   8 ;
            }
            
else
            {
                zeros 
=   63   -  m  +   56 ;
                size 
=  n  +   64   -  m  +   64 ;
            }

            ArrayList bs 
=   new  ArrayList(input);
            
if  (ones  ==   1 )
            {
                bs.Add((
byte ) 0x80 );  //  0x80 = $10000000
            }
            
for  ( int  i  =   0 ; i  <  zeros; i ++ )
            {
                bs.Add((
byte ) 0 );
            }

            UInt64 N 
=  (UInt64)n  *   8 ;
            
byte  h1  =  ( byte )(N  &   0xFF );
            
byte  h2  =  ( byte )((N  >>   8 &   0xFF );
            
byte  h3  =  ( byte )((N  >>   16 &   0xFF );
            
byte  h4  =  ( byte )((N  >>   24 &   0xFF );
            
byte  h5  =  ( byte )((N  >>   32 &   0xFF );
            
byte  h6  =  ( byte )((N  >>   40 &   0xFF );
            
byte  h7  =  ( byte )((N  >>   48 &   0xFF );
            
byte  h8  =  ( byte )(N  >>   56 );
            bs.Add(h1);
            bs.Add(h2);
            bs.Add(h3);
            bs.Add(h4);
            bs.Add(h5);
            bs.Add(h6);
            bs.Add(h7);
            bs.Add(h8);
            
byte [] ts  =  ( byte [])bs.ToArray( typeof ( byte ));

            
/*  Decodes input (byte[]) into output (UInt32[]). 
             * Assumes input length is a multiple of 4.
             
*/
            UInt32[] output 
=   new  UInt32[size  /   4 ];
            
for  (Int64 i  =   0 , j  =   0 ; i  <  size; j ++ , i  +=   4 )
            {
                output[j] 
=  (UInt32)(ts[i]  |  ts[i  +   1 <<   8   |  ts[i  +   2 <<   16   |  ts[i  +   3 <<   24 );
            }
            
return  output;
        }
        
private   static  UInt32[] MD5_Trasform(UInt32[] x)
        {

            UInt32 a, b, c, d;

            
for  ( int  k  =   0 ; k  <  x.Length; k  +=   16 )
            {
                a 
=  A;
                b 
=  B;
                c 
=  C;
                d 
=  D;

                
/*  Round 1  */
                FF(
ref  a, b, c, d, x[k  +   0 ], S11,  0xd76aa478 );  /*  1  */
                FF(
ref  d, a, b, c, x[k  +   1 ], S12,  0xe8c7b756 );  /*  2  */
                FF(
ref  c, d, a, b, x[k  +   2 ], S13,  0x242070db );  /*  3  */
                FF(
ref  b, c, d, a, x[k  +   3 ], S14,  0xc1bdceee );  /*  4  */
                FF(
ref  a, b, c, d, x[k  +   4 ], S11,  0xf57c0faf );  /*  5  */
                FF(
ref  d, a, b, c, x[k  +   5 ], S12,  0x4787c62a );  /*  6  */
                FF(
ref  c, d, a, b, x[k  +   6 ], S13,  0xa8304613 );  /*  7  */
                FF(
ref  b, c, d, a, x[k  +   7 ], S14,  0xfd469501 );  /*  8  */
                FF(
ref  a, b, c, d, x[k  +   8 ], S11,  0x698098d8 );  /*  9  */
                FF(
ref  d, a, b, c, x[k  +   9 ], S12,  0x8b44f7af );  /*  10  */
                FF(
ref  c, d, a, b, x[k  +   10 ], S13,  0xffff5bb1 );  /*  11  */
                FF(
ref  b, c, d, a, x[k  +   11 ], S14,  0x895cd7be );  /*  12  */
                FF(
ref  a, b, c, d, x[k  +   12 ], S11,  0x6b901122 );  /*  13  */
                FF(
ref  d, a, b, c, x[k  +   13 ], S12,  0xfd987193 );  /*  14  */
                FF(
ref  c, d, a, b, x[k  +   14 ], S13,  0xa679438e );  /*  15  */
                FF(
ref  b, c, d, a, x[k  +   15 ], S14,  0x49b40821 );  /*  16  */

                
/*  Round 2  */
                GG(
ref  a, b, c, d, x[k  +   1 ], S21,  0xf61e2562 );  /*  17  */
                GG(
ref  d, a, b, c, x[k  +   6 ], S22,  0xc040b340 );  /*  18  */
                GG(
ref  c, d, a, b, x[k  +   11 ], S23,  0x265e5a51 );  /*  19  */
                GG(
ref  b, c, d, a, x[k  +   0 ], S24,  0xe9b6c7aa );  /*  20  */
                GG(
ref  a, b, c, d, x[k  +   5 ], S21,  0xd62f105d );  /*  21  */
                GG(
ref  d, a, b, c, x[k  +   10 ], S22,  0x2441453 );  /*  22  */
                GG(
ref  c, d, a, b, x[k  +   15 ], S23,  0xd8a1e681 );  /*  23  */
                GG(
ref  b, c, d, a, x[k  +   4 ], S24,  0xe7d3fbc8 );  /*  24  */
                GG(
ref  a, b, c, d, x[k  +   9 ], S21,  0x21e1cde6 );  /*  25  */
                GG(
ref  d, a, b, c, x[k  +   14 ], S22,  0xc33707d6 );  /*  26  */
                GG(
ref  c, d, a, b, x[k  +   3 ], S23,  0xf4d50d87 );  /*  27  */
                GG(
ref  b, c, d, a, x[k  +   8 ], S24,  0x455a14ed );  /*  28  */
                GG(
ref  a, b, c, d, x[k  +   13 ], S21,  0xa9e3e905 );  /*  29  */
                GG(
ref  d, a, b, c, x[k  +   2 ], S22,  0xfcefa3f8 );  /*  30  */
                GG(
ref  c, d, a, b, x[k  +   7 ], S23,  0x676f02d9 );  /*  31  */
                GG(
ref  b, c, d, a, x[k  +   12 ], S24,  0x8d2a4c8a );  /*  32  */

                
/*  Round 3  */
                HH(
ref  a, b, c, d, x[k  +   5 ], S31,  0xfffa3942 );  /*  33  */
                HH(
ref  d, a, b, c, x[k  +   8 ], S32,  0x8771f681 );  /*  34  */
                HH(
ref  c, d, a, b, x[k  +   11 ], S33,  0x6d9d6122 );  /*  35  */
                HH(
ref  b, c, d, a, x[k  +   14 ], S34,  0xfde5380c );  /*  36  */
                HH(
ref  a, b, c, d, x[k  +   1 ], S31,  0xa4beea44 );  /*  37  */
                HH(
ref  d, a, b, c, x[k  +   4 ], S32,  0x4bdecfa9 );  /*  38  */
                HH(
ref  c, d, a, b, x[k  +   7 ], S33,  0xf6bb4b60 );  /*  39  */
                HH(
ref  b, c, d, a, x[k  +   10 ], S34,  0xbebfbc70 );  /*  40  */
                HH(
ref  a, b, c, d, x[k  +   13 ], S31,  0x289b7ec6 );  /*  41  */
                HH(
ref  d, a, b, c, x[k  +   0 ], S32,  0xeaa127fa );  /*  42  */
                HH(
ref  c, d, a, b, x[k  +   3 ], S33,  0xd4ef3085 );  /*  43  */
                HH(
ref  b, c, d, a, x[k  +   6 ], S34,  0x4881d05 );  /*  44  */
                HH(
ref  a, b, c, d, x[k  +   9 ], S31,  0xd9d4d039 );  /*  45  */
                HH(
ref  d, a, b, c, x[k  +   12 ], S32,  0xe6db99e5 );  /*  46  */
                HH(
ref  c, d, a, b, x[k  +   15 ], S33,  0x1fa27cf8 );  /*  47  */
                HH(
ref  b, c, d, a, x[k  +   2 ], S34,  0xc4ac5665 );  /*  48  */

                
/*  Round 4  */
                II(
ref  a, b, c, d, x[k  +   0 ], S41,  0xf4292244 );  /*  49  */
                II(
ref  d, a, b, c, x[k  +   7 ], S42,  0x432aff97 );  /*  50  */
                II(
ref  c, d, a, b, x[k  +   14 ], S43,  0xab9423a7 );  /*  51  */
                II(
ref  b, c, d, a, x[k  +   5 ], S44,  0xfc93a039 );  /*  52  */
                II(
ref  a, b, c, d, x[k  +   12 ], S41,  0x655b59c3 );  /*  53  */
                II(
ref  d, a, b, c, x[k  +   3 ], S42,  0x8f0ccc92 );  /*  54  */
                II(
ref  c, d, a, b, x[k  +   10 ], S43,  0xffeff47d );  /*  55  */
                II(
ref  b, c, d, a, x[k  +   1 ], S44,  0x85845dd1 );  /*  56  */
                II(
ref  a, b, c, d, x[k  +   8 ], S41,  0x6fa87e4f );  /*  57  */
                II(
ref  d, a, b, c, x[k  +   15 ], S42,  0xfe2ce6e0 );  /*  58  */
                II(
ref  c, d, a, b, x[k  +   6 ], S43,  0xa3014314 );  /*  59  */
                II(
ref  b, c, d, a, x[k  +   13 ], S44,  0x4e0811a1 );  /*  60  */
                II(
ref  a, b, c, d, x[k  +   4 ], S41,  0xf7537e82 );  /*  61  */
                II(
ref  d, a, b, c, x[k  +   11 ], S42,  0xbd3af235 );  /*  62  */
                II(
ref  c, d, a, b, x[k  +   2 ], S43,  0x2ad7d2bb );  /*  63  */
                II(
ref  b, c, d, a, x[k  +   9 ], S44,  0xeb86d391 );  /*  64  */

                A 
+=  a;
                B 
+=  b;
                C 
+=  c;
                D 
+=  d;
            }
            
return   new  UInt32[] { A, B, C, D };
        }
        
///   <summary>
        
///  Ms the d5 array.
        
///   </summary>
        
///   <param name="input"> The input. </param>
        
///   <returns></returns>
         public   static   byte [] MD5Array( byte [] input)
        {
            MD5_Init();
            UInt32[] block 
=  MD5_Append(input);
            UInt32[] bits 
=  MD5_Trasform(block);

            
/*  Encodes bits (UInt32[]) into output (byte[]). Assumes len is
             * a multiple of 4.
             
*/
            
byte [] output  =   new   byte [bits.Length  *   4 ];
            
for  ( int  i  =   0 , j  =   0 ; i  <  bits.Length; i ++ , j  +=   4 )
            {
                output[j] 
=  ( byte )(bits[i]  &   0xff );
                output[j 
+   1 =  ( byte )((bits[i]  >>   8 &   0xff );
                output[j 
+   2 =  ( byte )((bits[i]  >>   16 &   0xff );
                output[j 
+   3 =  ( byte )((bits[i]  >>   24 &   0xff );
            }
            
return  output;
        }

        
///   <summary>
        
///  Arrays to hex string.
        
///   </summary>
        
///   <param name="array"> The array. </param>
        
///   <param name="uppercase"> if set to  <c> true </c>  [uppercase]. </param>
        
///   <returns></returns>
         public   static   string  ArrayToHexString( byte [] array,  bool  uppercase)
        {
            
string  hexString  =   "" ;
            
string  format  =  uppercase  ?   " X2 "  :  " x2 " ;
            
foreach  ( byte  b  in  array)
            {
                hexString 
+=  b.ToString(format);
            }
            
return  hexString;
        }

        
///   <summary>
        
///  MDs the string.
        
///   </summary>
        
///   <param name="message"> The message. </param>
        
///   <returns></returns>
         public   static   string  MDString( string  message)
        {
            
char [] c  =  message.ToCharArray();
            
byte [] b  =   new   byte [c.Length];
            
for  ( int  i  =   0 ; i  <  c.Length; i ++ )
            {
                b[i] 
=  ( byte )c[i];
            }
            
byte [] digest  =  MD5Array(b);
            
return  ArrayToHexString(digest,  false );
        }
        
///   <summary>
        
///  MDs the file.
        
///   </summary>
        
///   <param name="fileName"> Name of the file. </param>
        
///   <returns></returns>
         public   static   string  MDFile( string  fileName)
        {
            FileStream fs 
=  File.Open(fileName, FileMode.Open, FileAccess.Read);
            
byte [] array  =   new   byte [fs.Length];
            fs.Read(array, 
0 , ( int )fs.Length);
            
byte [] digest  =  MD5Array(array);
            fs.Close();
            
return  ArrayToHexString(digest,  false );
        }

        
///   <summary>
        
///  Tests the specified message.
        
///   </summary>
        
///   <param name="message"> The message. </param>
        
///   <returns></returns>
         public   static   string  Test( string  message)
        {
            
return   " \r\nMD5 (\ ""  + message +  " \ " ) =  "   +  MD5.MDString(message);
        }
        
///   <summary>
        
///  Tests the suite.
        
///   </summary>
        
///   <returns></returns>
         public   static   string  TestSuite()
        {
            
string  s  =   "" ;
            s 
+=  Test( "" );
            s 
+=  Test( " a " );
            s 
+=  Test( " abc " );
            s 
+=  Test( " message digest " );
            s 
+=  Test( " abcdefghijklmnopqrstuvwxyz " );
            s 
+=  Test( " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 " );
            s 
+=  Test( " 12345678901234567890123456789012345678901234567890123456789012345678901234567890 " );
            
return  s;
        }
    }

 

 

 

转载于:https://www.cnblogs.com/rufi/archive/2010/01/02/1637968.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值