Using system;
Using system. Collections. Generic;
Using system. text;
Using system. collections;
Using system. IO;
Namespace your namespace name
{
Class MD5
{
// Static state variables
Private Static uint32;
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 MD5 functions.
* Four non-linear 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 ))
*
* (&, | Or ,~ Non, ^ exclusive or)
*/
Private Static uint32 F (uint32 X, uint32 y, uint32 Z)
{
Return (X & Y) | ((~ X) & Z );
}
Private Static uint32 g (uint32 X, uint32 y, uint32 Z)
{
Return (X & z) | (Y &(~ Z ));
}
Private Static uint32 H (uint32 X, uint32 y, uint32 Z)
{
Return x ^ y ^ Z;
}
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 Len 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 =;
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 + =;
B + = B;
C + = C;
D + = D;
}
Return new uint32 [] {a, B, c, d };
}
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;
}
Public static string arraytohexstring (byte [] array, bool uppercase)
{
String hexstring = "";
String format = "X2 ";
If (uppercase)
{
Format = "X2 ";
}
Foreach (byte B in array)
{
Hexstring + = B. tostring (format );
}
Return hexstring;
}
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 );
}
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 );
}
}
}