/ ********************************************************** MD5 Java bean @ Author: Topcat Tuppinlast Modified: 10, Mar, 2001 ********************************************* ************** / package Netkiller.security; import java.lang.reflect. *; / ******************* **************************** MD5 class implements RSA Data Security, Inc. MD5 Message in RFC1321 submitted to IETF -digest algorithm. ********************************************************* /
Public Class MD5 {/ * The following S11-S44 is actually a matrix of 4 * 4, which is implemented in the original C implementation. Here, it is intended to become STATIC final, which is read-only. Multiple instances between 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}; / * The following three members are the MD5 calculation process The three core data used, is defined 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, is the latest calculation result 16 Encontinence ASCII said. * / Public string DigestHexStr; / * Digest, is the latest internal representation of the latest calculation result, indicating 128bit MD5 value. * / Private byte [] Digest = new byte [16]; / * getMD5ofstr It is the most important public method of class MD5. The entrance parameter is the string of the MD5 transform returns to change the result, which 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 <16; i ) ) {DigestHexStr = bytehex (Digest [i]);} Return DigestHexStr;} // This is the standard constructor of MD5 class, JavaBean requires a PUBLIC and has no parameters of constructor PUBLIC MD5 () {md5init () ;
Return;}
/ * 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, i is 4 basic MD5 functions, in the original In the MD5 C implementation, since they are simple bit operations, they may be implemented as a macro, in Java, in Java, the name is 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 for near-one-step conversion 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 Long AC) {a = h (b, c, d) x ac; a = (int) a << s) | (INT) A >>> (32 - s)); A = B; RETURN A; (INT) A << S) | (int) a >>> (32 - s)); A = B; Return A;} / * md5Update is the master calculation process of MD5, INBUF is the word to be transformed String, inputlen is the length, this function is called by getmd5ofstr, before calling MD5init, so it is designed to private * / private void md5Update (byte [] inbuf, int inputlen) {INT I, INDEX, Partlen; Byte [ ] B Lock = 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 Else i = 0; /// * buffer remaining input * / md5memcpy (buffer, Inbuf, INDEX, I, INPUTLEN - I); } / * Md5final finishing and filling out the output * / 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 the INPOS INPOS, starting the byte of the LEN length to Output's Outpos location * / Private void md5memcpy (byte [] Output, Byte [] Input, Int outpos, int inpos, int LEN) {INT i For (i = 0; i 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, 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 disassembles the long array in order, because Java's long type is 64bit, only 32bit, to accommodate the original CTET * / private void Encode (byte [] Output, long [] Input , int LEN) {INT I, J; For (i = 0, j = 0; j For (i = 0, j = 0; j Return;} / * b2iu is a "upgraded" program I wrote by the principle of the principle that does not consider the correct mark, 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 number into hexadecimal ASCII said that because of byte's toString in Java unable to achieve this, we have no 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); returnz} public string GETMD5STRING (STRING MD5) {Return getMD5ofstr (md5) .tolowercase ();} 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]));}}