Java MD5 Algorithm __ Code

Source: Internet
Author: User
Tags md5

/**
* Java Bean for USAGE:MD5 algorithm
*
* FileName:MD5.java
* PackageName:org.ahpo.security
* Author:ahpo Yang
* Createdate:2006-4-24 14:47:11
*/
Package org.ahpo.security;

Import java.lang.reflect.*;

/*******************************************************************************
* The MD5 class implements the MD5 Message-digest algorithm for RSA Data Security, Inc., in RFC1321 submitted to the IETF.
******************************************************************************/

public class MD5 {
/*
* The following s11-s44 are actually a 4*4 matrix, implemented in the original C implementation using #define, which are implemented as static
* Final is to represent read-only, can be shared among multiple instance in the same process space
*/
static final int S11 = 7;

static final int S12 = 12;

static final int S13 = 17;

static final int S14 = 22;

static final int S21 = 5;

static final int S22 = 9;

static final int S23 = 14;

static final int S24 = 20;

static final int S31 = 4;

static final int S32 = 11;

static final int S33 = 16;

static final int S34 = 23;

static final int S41 = 6;

static final int S42 = 10;

static final int S43 = 15;

static final int S44 = 21;

Static final byte[] PADDING = {-128, 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};

/*
* The following three members are the 3 core data used in the MD5 calculation and are defined in the original C implementation in the MD5_CTX structure
*
*/
Private long[] state = new LONG[4]; State (ABCD)

Private long[] count = new long[2]; Number of bits, modulo 2^64 (LSB

First

Private byte[] buffer = new BYTE[64]; Input buffer

/*
* DIGESTHEXSTR is the only public member of the MD5, and is the most recent computed result of the 16-in-ASCII representation.
*/
Public String Digesthexstr;

/*
* Digest, is the most recent calculation results of the 2 internal representation, representing the 128bit MD5 value.
*/
Private byte[] Digest = new BYTE[16];

/*
* GETMD5OFSTR is the main public method of class MD5, and the entry parameter is the string you want to MD5 transform
* Return is the result of the transformation, the result is obtained from the public member Digesthexstr.
*/
public string Getmd5ofstr (string inbuf) {
Md5init ();
Md5update (Inbuf.getbytes (), inbuf.length ());
Md5final ();
Digesthexstr = "";
for (int i = 0; i < i++) {
Digesthexstr + + Bytehex (Digest[i]);
}
return digesthexstr;

}

This is the standard constructor for this class of MD5, JavaBean requires a constructor that is public and has no parameters
Public MD5 () {
Md5init ();

Return
}

/* Md5init is an initialization function that initializes the core variable and loads the standard magic number.
private void Md5init () {
Count[0] = 0L;
COUNT[1] = 0L;
/* Load Magic Initialization constants.

State[0] = 0x67452301l;
STATE[1] = 0xefcdab89l;
STATE[2] = 0x98badcfel;
STATE[3] = 0x10325476l;

Return
}

/*
* F, G, H, I are 4 basic MD5 functions, in the original MD5 C implementation, because they are
* Simple bit operations, which can be implemented as macros for efficiency reasons, in Java, we've implemented them as private methods, with names kept in the original C.
*/

Private long F (long x, long y, long Z) {
Return (x & y) | ((~x) & Z);

}

Private long G (long x, long y, long Z) {
Return (X & Z) | (Y & (~z));

}

Private long H (long x, long y, long Z) {
return x ^ y ^ z;
}

Private long I (long x, long y, long Z) {
Return y ^ (x | (~z));
}

/*
* FF,GG,HH and II will call f,g,h,i for a nearly one-step transform FF, GG, HH, and II transformations for
* Rounds 1, 2, 3, and 4. Rotation is separate from addition to prevent
* Recomputation.
*/

Private long FF (long A, long B, long C, long D, long X, long s, long AC) {
A + + F (b, C, D) + x + ac;
A = ((int) a << s) | ((int) a >>> (32-s));
A + b;
return A;
}

Private long GG (long A, long B, long C, long D, long X, long s, long AC) {
A + + G (b, C, D) + x + ac;
A = ((int) a << s) | ((int) a >>> (32-s));
A + b;
return A;
}

Private long HH (long A, long B, long C, long D, long X, long s, long AC) {
A + + H (b, C, D) + x + ac;
A = ((int) a << s) | ((int) a >>> (32-s));
A + b;
return A;
}

Private long II (long A, long B, long C, long D, long X, long s, long AC) {
A + = I (b, C, D) + x + ac;
A = ((int) a << s) | ((int) a >>> (32-s));
A + b;
return A;
}

/*
* Md5update is the MD5 of the main calculation process, INBUF is to transform the byte string, Inputlen is the length, this
* Function called by GETMD5OFSTR, call Md5init before calling, so design it as private
*/
private void Md5update (byte[] inbuf, int inputlen) {

int I, index, Partlen;
byte[] block = new BYTE[64];
index = (int) (Count[0] >>> 3) & 0x3F;
/* Update Number of bits * *
if ((count[0] + = (Inputlen << 3)) < (Inputlen << 3))
count[1]++;
COUNT[1] + + = (inputlen >>> 29);

Partlen = 64-index;

Transform as many times as possible.
if (Inputlen >= partlen) {
md5memcpy (buffer, INBUF, index, 0, Partlen);
Md5transform (buffer);

for (i = Partlen i + < Inputlen i + = 64) {

MD5MEMCPY (block, inbuf, 0, I, 64);
Md5transform (block);
}
index = 0;

} else

i = 0;

/* Buffer remaining input * *
md5memcpy (buffer, INBUF, index, I, inputlen-i);

}

/*
* Md5final Finishing and filling out output results
*/
private void Md5final () {
Byte[] bits = new BYTE[8];
int index, Padlen;

/* Save Number of bits * *
Encode (Bits, count, 8);

* * Pad out to 64 mod.
index = (int) (Count[0] >>> 3) & 0x3f;
Padlen = (Index < 56)? (56-index): (120-index);
Md5update (PADDING, Padlen);

/* Append length (before padding) * *
Md5update (Bits, 8);

/* Store State in Digest * *
Encode (Digest, State, 16);

}

/*
* md5memcpy is an internally used byte array of block copy functions, starting with the input of the inpos of Len length
* Byte copy to the output Outpos position start
*/

private void md5memcpy (byte[] output, byte[] input, int outpos, int inpos,
int len) {
int i;

for (i = 0; i < len; i++)
Output[outpos + i] = Input[inpos + i];
}

/*
* Md5transform is a MD5 core transformation program, with Md5update calls, block is a chunk of raw bytes
*/
private void Md5transform (byte block[]) {
Long a = state[0], B = state[1], c = state[2], d = state[3];
long[] x = new LONG[16];

Decode (x, block, 64);

/* Round 1 * *
A = FF (A, B, C, D, X[0], S11, 0xd76aa478l); /* 1 * *
D = FF (d, a, B, C, x[1], S12, 0xe8c7b756l); /* 2 * *
c = FF (c, D, a, B, x[2], S13, 0X242070DBL); /* 3 * *
b = FF (b, C, D, A, x[3], S14, 0xc1bdceeel); /* 4 * *
A = FF (A, B, C, D, X[4], S11, 0XF57C0FAFL); /* 5 * *
D = FF (d, a, B, C, x[5], S12, 0x4787c62al); /* 6 * *
c = FF (c, D, a, B, x[6], S13, 0xa8304613l); /* 7 * *
b = FF (b, C, D, A, x[7], S14, 0xfd469501l); /* 8 * *
A = FF (A, B, C, D, X[8], S11, 0x698098d8l); /* 9 * *
D = FF (d, a, B, C, x[9], S12, 0X8B44F7AFL); /* 10 * *
c = FF (c, D, a, B, x[10], S13, 0xffff5bb1l); /* 11 * *
b = FF (b, C, D, A, x[11], S14, 0x895cd7bel); /* 12 * *
A = FF (A, B, C, D, X[12], S11, 0x6b901122l); /* 13 * *
D = FF (d, a, B, C, x[13], S12, 0xfd987193l); /* 14 * *
c = FF (c, D, a, B, x[14], S13, 0xa679438el); /* 15 * *
b = FF (b, C, D, A, x[15], S14, 0x49b40821l); /* 16 * *

/* Round 2 * *
A = GG (A, B, C, D, X[1], S21, 0xf61e2562l); /* 17 * *
D = GG (d, a, B, C, x[6], S22, 0xc040b340l); /* 18 * *
c = GG (c, D, a, B, x[11], S23, 0x265e5a51l); /* 19 * *
b = GG (b, C, D, A, x[0], S24, 0xe9b6c7aal); /* 20 * *
A = GG (A, B, C, D, X[5], S21, 0XD62F105DL); /* 21 * *
D = GG (d, a, B, C, x[10], S22, 0x2441453l); /* 22 * *
c = GG (c, D, a, B, x[15], S23, 0xd8a1e681l); /* 23 * *
b = GG (b, C, D, A, x[4], S24, 0xe7d3fbc8l); /* 24 * *
A = GG (A, B, C, D, X[9], S21, 0x21e1cde6l); /* 25 * *
D = GG (d, a, B, C, x[14], S22, 0xc33707d6l); /* 26 * *
c = GG (c, D, a, B, x[3], S23, 0xf4d50d87l); /* 27 * *
b = GG (b, C, D, A, x[8], S24, 0x455a14edl); /* 28 * *
A = GG (A, B, C, D, X[13], S21, 0xa9e3e905l); /* 29 * *
D = GG (d, a, B, C, x[2], S22, 0xfcefa3f8l); /* 30 * *
c = GG (c, D, a, B, x[7], S23, 0x676f02d9l); /* 31 * *
b = GG (b, C, D, A, x[12], S24, 0x8d2a4c8al); /* 32 * *

/* Round 3 * *
A = HH (A, B, C, D, X[5], S31, 0xfffa3942l); /* 33 * *
D = HH (d, a, B, C, x[8], S32, 0x8771f681l); /* 34 * *
c = HH (c, D, a, B, x[11], S33, 0x6d9d6122l); /* 35 * *
b = HH (b, C, D, A, x[14], S34, 0xfde5380cl); /* 36 * *
A = HH (A, B, C, D, X[1], S31, 0xa4beea44l); /* 37 * *
D = HH (d, a, B, C, x[4], S32, 0x4bdecfa9l); /* 38 * *
c = HH (c, D, a, B, x[7], S33, 0xf6bb4b60l); /* 39 * *
b = HH (b, C, D, A, x[10], S34, 0xbebfbc70l); /* 40 * *
A = HH (A, B, C, D, X[13], S31, 0x289b7ec6l); /* 41 * *
D = HH (d, a, B, C, x[0], S32, 0xeaa127fal); /* 42 * *
c = HH (c, D, a, B, x[3], S33, 0xd4ef3085l); /* 43 * *
b = HH (b, C, D, A, x[6], S34, 0x4881d05l); /* 44 * *
A = HH (A, B, C, D, X[9], S31, 0xd9d4d039l); /* 45 * *
D = HH (d, a, B, C, x[12], S32, 0xe6db99e5l); /* 46 * *
c = HH (c, D, a, B, x[15], S33, 0x1fa27cf8l); /* 47 * *
b = HH (b, C, D, A, x[2], S34, 0xc4ac5665l); /* 48 * *

/* Round 4 * *
A = II (A, B, C, D, X[0], S41, 0xf4292244l); /* 49 * *
D = II (d, a, B, C, x[7], S42, 0x432aff97l); /* 50 * *
c = II (c, D, a, B, x[14], S43, 0xab9423a7l); /* 51 * *
b = II (b, C, D, A, x[5], S44, 0xfc93a039l); /* 52 * *
A = II (A, B, C, D, X[12], S41, 0x655b59c3l); /* 53 * *
D = II (d, a, B, C, x[3], S42, 0x8f0ccc92l); /* 54 * *
c = II (c, D, a, B, x[10], S43, 0XFFEFF47DL); /* 55 * *
b = II (b, C, D, A, x[1], S44, 0x85845dd1l); /* 56 * *
A = II (A, B, C, D, X[8], S41, 0X6FA87E4FL); /* 57 * *
D = II (d, a, B, C, x[15], S42, 0xfe2ce6e0l); /* 58 * *
c = II (c, D, a, B, x[6], S43, 0xa3014314l); /* 59 * *
b = II (b, C, D, A, x[13], S44, 0x4e0811a1l); /* 60 * *
A = II (A, B, C, D, X[4], S41, 0xf7537e82l); /* 61 * *
D = II (d, a, B, C, x[11], S42, 0xbd3af235l); /* 62 * *
c = II (c, D, a, B, x[2], S43, 0X2AD7D2BBL); /* 63 * *
b = II (b, C, D, A, x[9], S44, 0xeb86d391l); /* 64 * *

State[0] + = A;
STATE[1] + b;
STATE[2] + = C;
STATE[3] + = D;

}

/*
* Encode the long array into a byte array, because the Java long type is 64bit, only 32bit is removed to accommodate the original C implementation
*/
private void Encode (byte[] output, long[] input, int len) {
int I, J;

for (i = 0, j = 0; j < Len; i++, J + + 4) {
OUTPUT[J] = (byte) (Input[i] & 0xffL);
Output[j + 1] = (byte) ((Input[i] >>> 8) & 0xffL);
Output[j + 2] = (byte) ((Input[i) >>>) & 0xffL);
Output[j + 3] = (byte) ((Input[i] >>>) & 0xffL);
}
}

/*
* Decode the byte array into a long array in order because the long type of Java is 64bit,
* Synthesis of low 32bit, high 32bit Zero, to adapt to the original C implementation of the use
*/
private void Decode (long[] output, byte[] input, int len) {
int I, J;

for (i = 0, j = 0; j < Len; i++, J + + 4)
Output[i] = B2iu (Input[j]) | (B2iu (input[j + 1]) << 8)
| (B2iu (Input[j + 2]) << 16) | (B2iu (Input[j + 3]) << 24);

Return
}

/*
* B2iu is a "raise" program that I wrote about byte according to the principle of not taking the sign, because Java has no unsigned operation
*/
public static long B2iu (byte b) {
Return b < 0? B & 0x7F + 128:b;
}

 /*bytehex (), which converts the number of a byte to a 16-binary ASCII representation,
  because the byte ToString in Java does not achieve this, we do not have the
  in C language sprintf (Outbuf, "%02x", IB)
  */
 public static String Bytehex (Byte ib) {
  char[] Digit = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ' A ', ' B ', ' C ', ' D ', ' E ',
     ' F '};
  char[] ob = new char[2];
  ob[0] = digit[(ib >>> 4) & 0x0f];
  ob[1] = Digit[ib & 0x0f];
  string s = new String (OB);
  return S;
 }
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.