MD5 algorithm

zhaozj2021-02-16  71

Import java.lang.reflect. *;

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

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, 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. The entrance parameter is the string that you want to make MD5 transformation is changed, this result is obtained from 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 the class of MD5.

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, 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 >> 8) & 0xffl); OUTPUT [J 2] = (Byte) ((Input [I] >>> 16) & 0xffl); OUTPUT [J 3] = (Byte) (INPUT [I] >>> 24) & 0xffl);}}

/ * 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]));}

}

}

转载请注明原文地址:https://www.9cbs.com/read-13225.html

New Post(0)