Import java.lang.reflect. *;
/ * * The MD5 class implements the MD5 Message-Digest algorithm in RSA Data Security, Inc. submitted to IETF * RFC1321. * / public class md5 {/ * The following S11-S44 is actually a matrix of 4 * 4, in the original C implementation, using #define implementation, where it is intended to be STATIC Final, which is read-only, cut Multiple Instances can share * / private static final int S11 = 7 in the same process space * / private static final int S12 = 12; private static final int S13 = 17; private static final INT S14 = 22;
Private static final int S21 = 5; private static final int S22 = 9; private static final int S23 = 14; private static final int S24 = 20;
Private static final int S31 = 4; private static final int S32 = 11; private static final int S33 = 16; private static final Int S34 = 23;
Private static final int S41 = 6; private static final int S42 = 10; private static final int S43 = 15; private static final int S44 = 21;
Private 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}; / * The following three members are the MD5 calculation process 3 core data used in the original C implementation to the MD5_CTX structure in the original C implementation * / private long [] State = new long [4]; // state (abcd) private long [] count = new long [ 2]; // Number of Bits, MODULO 2 ^ 64 (LSB first) private bote [] buffer = new byte [64]; // input buffer
/ * DigestHexStr is the only public member of MD5, which is the 16-way ASCII representation of the latest calculation results. * / public string DigestHexStr;
/ * Digest, is the latest internal representation of the 2-time calculation result, indicating the 128bit MD5 value. * / private byte [] Digest = New Byte [16];
/ ** * getMD5ofstr is the most important public method of class MD5, and the entrance parameter is the string * returned to the MD5 transform. The result is obtained from the public member DigestHexStr. * @Param Inbuf * @Return * / public string getMD5Ofstr (String Inbuf) {md5init (); md5Update (), Inbuf.Length ()); md5final (); DigestHexStr = ""; for (int i = 0; i <16; i ) {DigestHexStr = bytehex (Digest [i]);} Return DigestHexStr;}
// This is the standard constructor of the class of MD5.
/ * md5init is an initialization function, initializing core variable, loading standard magic numbers * / 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, and i are four basic MD5 functions, in the original MD5 C implementation, because they are simple bit operations, it is possible for efficiency to be macro, in Java We implemented them into a Private method, the name maintained 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 to conduct near-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 < >> (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 < >> (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 < >> (32 - s)); A = B; Return A;
/ * Md5Update is the primary calculation process of MD5, INBUF is the byte string to be transformed. Inputlen is the length. This function is called by getmd5ofstr, and MD5init needs to be called before calling, so it is designed to private * / private void MD5Update ] 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> = Partle) {MD5memcpy (Buffer, Inbuf, INDEX, 0, PartLen); MD5Transform (Buffer);
For (i = partlen; i 63 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 the result * / private void md5Final () {byte [] bits = new byte [8]; int index, padlen; /// * save number of bits * / encode (bits, count, 8) ; /// * Pad out to 56 mod 64. Index = (int) (count [0] >>> 3) & 0x3f; padlen = (INDEX <56): (120 - index); md5Update (Padding, Padlen); /// * append length * / md5Update (BITS, 8); /// * Store State in Digest * / Encode (Digest, State, 16); } / * md5memcpy is a block copy function of an internal use Byte array, from INPOS, starting the LEN length byte to Outpos location start * / Private void md5memcpy (byte [] Output, Byte [] Input, Int outpos, int inpos, int LEN) {INT i For (i = 0; i / * MD5Transform is the MD5 core transform program, with MD5Update call, block is the original byte of the block * / 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, 0XC1BDCEEL); / * 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, 0XA4Bee44L); / * 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, 0xF429244L); / * 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, 0X2AD7D2BL); / * 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 disassembles the long array in order, because Java's long type is 64bit, only 32bit, to accommodate the purpose of the original C implementation * / private vid encode (byte [] Output, long [] Input, INT LEN) {INT I, J; For (i = 0, j = 0; j / * Decode syntheses the Byte array into a long array, because Java's long type is 64bit, only 32bit, high 32bit, to accommodate the original CT-implemented use * / private void decode (long [] Output, BYTE [] INPUT, INT LEN) {INT I, J; For (i = 0, j = 0; j } Return; / * B2IU is a "upgraded" program I wrote by the principle that does not consider the principle of the corrective number, because Java has no unsigned operation * / public static long b2iu (byte b) {RETURN B <0? B & 0x7F 128: B; / * bytehex (), used to convert a BYTE type to a hexadecimal ASCII said that because of the bitte of the Java can't achieve this, we don't have the sprintf in the C language (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;} Public static void main (string args []) { MD5 M = New MD5 (); if (array.getlength (args) == 0) {// If there is no parameters, the standard Test Suite System.out.println ("MD5 Test Suite:"); System.out.Println ("MD5 (/"): " M.getmd5ofstr (")); System.out.Println ("MD5 (/ "A /"): " M.getmd5ofstr (" a "))); system.out.println (" MD5 (/ "ABC /"): " M.getmd5ofstr (" ABC ")); system.out. println ( "MD5 (/" message digest / "):" m.getMD5ofStr ( "message digest")); System.out.println ( "MD5 (/" abcdefghijklmnopqrstuvwxyz / "):" m.getMD5ofStr ( "abcdefghijklmnopqrstuvwxyz ")); System.out.println (" MD5 (/ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 /"): " m.getMD5ofStr (" ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 "));} else {System.out.println (" MD5 ( " args [0] ") =" m.getmd5ofstr (args [0]));} } }