// After the MD5 algorithm is used to encrypt the password, A unique and irreversible string encoding is obtained. <br/> // The encrypted string encoding is stored as a password identifier in the database, it can prevent password theft in the database <br/> // and the encrypted string encoding cannot be converted to the original password, this ensures the security of passwords stored in the database <br/> // so during user verification, you cannot directly compare the logon password with the password identifier stored in the database <br/> // instead, you need to convert the user's logon password to MD5, <br/> // the following code implements the MD5 Algorithm to encrypt strings </P> <p>/** <br/> * implements the MD5 Algorithm to encrypt strings <br/> * @ see directly calls tomd5 () in the MD5 class () method <br/> * @ see to encrypt the string to be encrypted <br/> */<br/> public class MD5 {<br/> // The following S11- S44 is actually a 4*4 matrix. In the original C implementation, it is implemented using # define <br/> // here implementing them as static final indicates read-only, shared among multiple instances in the same process space <br/> static final int S11 = 7; <br/> static final int S12 = 12; <br/> static final int S13 = 17; <br/> static final int S14 = 22; <br/> static final int S21 = 5; <br/> static final int s22 = 9; <br/> static final int S23 = 14; <br/> static final int S24 = 20; <br/> static final int s31 = 4; <br/> static final I NT s32 = 11; <br/> static final int s33 = 16; <br/> static final int s34 = 23; <br/> static final int s41 = 6; <br/> static final int S42 = 10; <br/> static final int s43 = 15; <br/> static final int s44 = 21; <br/> static final byte [] padding = {-128, 0, 0, 0, 0, 0, 0, 0, 0, <br/> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, <br/> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, <br/> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; </P> <p>/** <br/> * the following three members are the three core data used in MD5 calculation, the md5_ctx structure is defined in the original C implementation. <br/> */<br/> private long [] State = new long [4]; // state () <br/> private long [] Count = new long [2]; // number of BITs, modulo 2 ^ 64 (ISB first) <br/> private byte [] buffer = new byte [64]; // input buffer </P> <p> // digesthexstr is the only public member of md5.java, is the hexadecimal ASCII representation of the latest calculation result <br/> // This variable contains the input string ASCII code of the 128-bit MD5 code after MD5 calculation <br/> Public String digesthexstr; </P> <p> // digest is the binary internal representation of the latest calculation result, MD5 value of BITs <br/> private byte [] digest = new byte [16]; </P> <p>/** <br/> * this is the most common MD5-like method. <br/> * @ Param inbuf the entry parameter is the string you want to perform MD5 conversion. <br/> * @ return returns the transformed result, this result is obtained from the public member digesthexstr <br/> */<br/> Public String getmd5ofstr (string inbuf) {<br/> md5init (); <br/> md5update (inbuf. getbytes (), inbuf. length (); <br/> MD5 Final (); <br/> digesthexstr = ""; <br/> for (INT I = 0; I <16; I ++) {<br/> digesthexstr + = bytehex (Digest [I]); <br/>}< br/> return digesthexstr; <br/>}</P> <p>/** <br/> * this is the standard constructor of the MD5 class, javaBean requires a public constructor without parameters <br/> */<br/> Public MD5 () {<br/> md5init (); <br/> return; <br/>}</P> <p>/** <br/> * This is an initialization function that initializes core variables, load Standard Functions <br/> */<br/> private void md5init () {<br/> count [0] = 0l; <br/> count [1] = 0l; <br/>/ /Load magic initialization constants <br/> State [0] = 0x67452301l; <br/> State [1] = 0xefcdab89l; <br/> State [2] = 0x98badcfel; <br/> State [3] = 0x10325476l; <br/>}</P> <p> // F, G, H, I is four basic MD5 functions <br/> // In the original MD5 C implementation, because they are simple bitwise operations, they may be implemented as macros for efficiency reasons <br/> // in Java, we implement them as private methods, the name remains in the original C <br/> private long F (long X, long y, long Z) {<br/> return (X & Y) | ((~ X) & Z); <br/>}< br/> private long g (long X, long y, long Z) {<br/> return (X & Z) | (Y &(~ Z); <br/>}< br/> private long H (long X, long y, long Z) {<br/> return x ^ y ^ Z; <br/>}< br/> private long I (long X, long y, long Z) {<br/> return y ^ (X | (~ Z); <br/>}</P> <p>/FF, GG, HH, and II call F, G, H, I for further transformation <br/> // ff, GG, HH and II transformations for Rounds 1, 2, 3 and 4 <br/> // rotation is separate from addition to prevent recomputation <br/> private long ff (long a, long B, long C, long d, long X, long s, long AC) {<br/> A + = f (B, c, d) + x + AC; <br/> A = (INT) A <s) | (INT) A >>> (32-s); <br/> A + = B; <br/> return; <br/>}< br/> private long Gg (long A, long B, long C, long d, long X, long s, long AC) {<br/> A + = g (B, c, d) + x + AC; <br/> A = (INT) A <s) | (INT) A >>> (32-s )); <br/> A + = B; <br/> return a; <br/>}< br/> private long HH (long a, long B, long c, long D, long X, long s, long AC) {<br/> A + = H (B, c, d) + x + AC; <br/> A = (INT) A <s) | (INT) A> (32-s); <br/> A + = B; <br/> return a; <br/>}< br/> private long II (long a, long B, long c, Long d, long X, long s, long AC) {<br/> A + = I (B, C, D) + x + AC; <br/> A = (INT) A <s) | (INT) A> (32-s); <br/> A + = B; <br/> return a; <br/>}</P> <p>/** <br/> * this is the main MD5 calculation process. This function is called by getmd5ofstr <br/> * @ see. Before calling this function, you must call md5init, therefore, it is designed as a private <br/> * @ Param inbuf: the MD5 encrypted byte string <br/> * @ Param inputlen String Length <br/> */<br /> private void md5update (byte [] inbuf, int inputlen) {<br/> int I, index, partlen; <br/> byte [] block = new byte [64]; <br/> Index = (INT) (count [0] >>> 3) & 0x3f; <br/> // UPDATE Number of BITs <br/> If (count [0] + = (inputlen <3) <(inputlen <3 )) <br/> count [1] ++; <Br/> count [1] + = (inputlen> 29); <br/> partlen = 64-index; <br/> // transform as usual times as possible <br/> If (inputlen> = partlen) {<br/> md5memcpy (buffer, inbuf, index, 0, partlen); <br/> md5transform (buffer); <br/> for (I = partlen; I + 63 <inputlen; I ++ = 64) {<br/> md5memcpy (Block, inbuf, 0, I, 64); <br/> md5transform (Block); <br/>}< br/> Index = 0; <br/>} else <br/> I = 0; <br/> // buffer remaining input <B R/> md5memcpy (buffer, inbuf, index, I, inputlen-I ); <br/>}</P> <p>/** <br/> * sort and enter the output result. <br/> * @ see returns the 128 bits (16 bytes)) the MD5 code of is stored in the Digest array <br/> */<br/> private void md5final () {<br/> byte [] bits = new byte [8]; <br/> int index, padlen; <br/> // save Number of BITs <br/> encode (bits, Count, 8 ); <br/> // pad out to 56 mod 64 <br/> Index = (INT) (count [0]> 3) & 0x3f; <br/> padlen = (index <56 )? (56-index): (120-index); <br/> md5update (padding, padlen); <br/> // append length (before padding) <br/> md5update (bits, 8); <br/> // store state in Digest <br/> encode (Digest, state, 16 ); <br/>}</P> <p>/** <br/> * This is a block copy function of the byte array used internally. <br/> * @ see from input inpos starts to copy the Len length bytes to the outpos position of the output. <br/> */<br/> private void md5memcpy (byte [] output, byte [] input, int outpos, int inpos, int Len) {<br/> int I; <br /> For (I = 0; I <Len; I ++) <br/> output [outpos + I] = input [inpos + I]; <br/>}</P> <p>/** <br/> * This is the MD5 core Conversion Program. Called by md5update <br/> * @ Param block, the original byte of the block <br/> */<br/> private void md5transform (byte block []) {<br/> long a = State [0], B = State [1], c = State [2], D = State [3]; <br/> long [] x = new long [16]; <br/> decode (x, block, 64 ); <br/>/* Round 1 */<br/> A = ff (a, B, c, d, X [0], S11, 0xd76aa478l ); // 1 <br/> d = ff (D, a, B, c, X [1], S12, 0xe8c7b756l ); // 2 <br/> C = ff (c, d, A, B, X [2], S13, 0x242070dbl); // 3 <br/> B = f F (B, c, d, A, X [3], S14, 0xc1bdceeel); // 4 <br/> A = ff (a, B, c, d, X [4], S11, 0xf57c0fafl); // 5 <br/> d = ff (D, a, B, c, X [5], S12, 0x4787c62al ); // 6 <br/> C = ff (c, d, A, B, X [6], S13, 0xa8304613l ); // 7 <br/> B = ff (B, c, d, A, X [7], S14, 0xfd469501l ); // 8 <br/> A = ff (a, B, c, d, X [8], S11, 0x698098d8l ); // 9 <br/> d = ff (D, a, B, c, X [9], S12, 0x8b44f7afl ); // 10 <br/> C = ff (c, d, A, B, X [10], S 13, 0xffff5bb1l); // 11 <br/> B = ff (B, c, d, A, X [11], S14, 0x895cd7bel ); // 12 <br/> A = ff (a, B, c, d, X [12], S11, 0x6b901122l ); // 13 <br/> d = ff (D, a, B, c, X [13], S12, 0xfd987193l ); // 14 <br/> C = ff (c, d, A, B, X [14], S13, 0xa679438el ); // 15 <br/> B = ff (B, c, d, A, X [15], S14, 0x49b40821l ); // 16 <br/>/* Round 2 */<br/> A = Gg (a, B, c, d, X [1], S21, 0xf61e2562l ); // 17 <br/> d = Gg (D, a, B, c, X [6], S 22, 0xc040b340l); // 18 <br/> C = Gg (c, d, A, B, X [11], S23, 0x265e5a51l ); // 19 <br/> B = Gg (B, c, d, A, X [0], S24, 0xe9b6c7aal ); // 20 <br/> A = Gg (a, B, c, d, X [5], S21, 0xd62f105dl ); // 21 <br/> d = Gg (D, a, B, c, X [10], s22, 0x2441453l ); // 22 <br/> C = Gg (c, d, A, B, X [15], S23, 0xd8a1e681l ); // 23 <br/> B = Gg (B, c, d, A, X [4], S24, 0xe7d3fbc8l ); // 24 <br/> A = Gg (a, B, c, d, X [9], S21, 0x21e1cde6l );// 25 <br/> d = Gg (D, a, B, c, X [14], s22, 0xc33707d6l); // 26 <br/> C = Gg (C, d, a, B, X [3], S23, 0xf4d50d87l); // 27 <br/> B = Gg (B, c, d, A, X [8], s24, 0x455a14edl); // 28 <br/> A = Gg (a, B, c, d, X [13], S21, 0xa9e3e905l ); // 29 <br/> d = Gg (D, a, B, c, X [2], s22, 0xfcefa3f8l ); // 30 <br/> C = Gg (c, d, A, B, X [7], S23, 0x676f02d9l ); // 31 <br/> B = Gg (B, c, d, A, X [12], S24, 0x8d2a4c8al ); // 32 <br/>/* Round 3 */ <Br/> A = HH (a, B, c, d, X [5], s31, 0xfffa3942l); // 33 <br/> d = HH (D, a, B, C, X [8], s32, 0x8771f681l); // 34 <br/> C = HH (c, d, A, B, X [11], s33, 0x6d9d6122l); // 35 <br/> B = HH (B, c, d, A, X [14], s34, 0xfde5380cl ); // 36 <br/> A = HH (a, B, c, d, X [1], s31, 0xa4beea44l ); // 37 <br/> d = HH (D, a, B, c, X [4], s32, 0x4bdecfa9l ); // 38 <br/> C = HH (c, d, A, B, X [7], s33, 0xf6bb4b60l ); // 39 <br/> B = HH (B, c, d, A, X [10], s34, 0xbebfbc70l); // 40 <br/> A = HH (a, B, c, d, X [13], s31, 0x289b7ec6l); // 41 <br/> d = HH (D, a, B, c, X [0], s32, 0xeaa1_fal ); // 42 <br/> C = HH (c, d, A, B, X [3], s33, 0xd4ef3085l ); // 43 <br/> B = HH (B, c, d, A, X [6], s34, 0x4881d05l ); // 44 <br/> A = HH (a, B, c, d, X [9], s31, 0xd9d4d039l ); // 45 <br/> d = HH (D, a, B, c, X [12], s32, 0xe6db99e5l ); // 46 <br/> C = HH (c, d, A, B, X [15], s33, 0x1 Fa27cf8l); // 47 <br/> B = HH (B, c, d, A, X [2], s34, 0xc4ac5665l ); // 48 <br/>/* Round 4 */<br/> A = II (a, B, c, d, X [0], s41, 0xf4292244l ); // 49 <br/> d = II (D, a, B, c, X [7], S42, 0x432aff97l ); // 50 <br/> C = II (c, d, A, B, X [14], s43, 0xab9423a7l ); // 51 <br/> B = II (B, c, d, A, X [5], s44, 0xfc93a039l ); // 52 <br/> A = II (a, B, c, d, X [12], s41, 0x655b59c3l ); // 53 <br/> d = II (D, a, B, c, X [3], S42, 0x8f0c Cc92l); // 54 <br/> C = II (c, d, A, B, X [10], s43, 0xfeff47dl ); // 55 <br/> B = II (B, c, d, A, X [1], s44, 0x85845dd1l ); // 56 <br/> A = II (a, B, c, d, X [8], s41, 0x6fa87e4fl ); // 57 <br/> d = II (D, a, B, c, X [15], S42, 0xfe2ce6e0l ); // 58 <br/> C = II (c, d, A, B, X [6], s43, 0xa3014314l ); // 59 <br/> B = II (B, c, d, A, X [13], s44, 0x4e0811a1l ); // 60 <br/> A = II (a, B, c, d, X [4], s41, 0xf7537e82l); // 61 <br/> d = II (D, a, B, c, X [11], S42, 0xbd3af235l); // 62 <br/> C = II (c, d, A, B, X [2], s43, 0x2ad7d2bbl); // 63 <br/> B = II (B, c, d, A, X [9], s44, 0xeb86d391l ); // 64 <br/> State [0] + = A; <br/> State [1] + = B; <br/> State [2] + = C; <br/> State [3] + = D; <br/>}</P> <p>/** <br/> * split the long array into byte arrays in sequence <br/> * @ see because of the long type of Java yes 64bit, only 32 bits are removed to adapt to the original C implementation. <br/> */<br/> private void encode (byte [] output, long [] input, in T Len) {<br/> int I, j; <br/> for (I = 0, j = 0; j <Len; I ++, J + = 4) {<br/> output [J] = (byte) (input [I] & 0 xffl); <br/> output [J + 1] = (byte) (input [I] >>> 8) & 0 xffl); <br/> output [J + 2] = (byte) (input [I] >>> 16) & 0 xffl); <br/> output [J + 3] = (byte) (input [I] >>> 24) & 0 xffl ); <br/>}</P> <p>/** <br/> * merges byte arrays into long arrays in sequence. <br/> * @ see because Java's long type is 64bit, only low 32bit is merged and high 32bit is cleared to adapt to the use of the original C implementation <br/> */<br/> private void Decode (long [] output, byte [] input, int Len) {<br/> int I, j; <br/> for (I = 0, j = 0; j <Len; I ++, J + = 4) <br/> output [I] = b2iu (input [J]) | (b2iu (input [J + 1]) <8) | (b2iu (input [J + 2]) <16) | (b2iu (input [J + 3]) <24 ); <br/> return; <br/>}</P> <p>/** <br/> * convert the number of characters in one byte to an unsigned long value. <br/> * @ see this method is a "ascending Byte" program that does not consider positive and negative signs <br/> * @ see Because Java does not have unsigned Operations <br/> */<br /> Public static long b2iu (byte B) {<br/> // or Re Turn B> = 0? B: B & 0xff; <br/> return B <0? B & amp; 0x7f + 128: B; <br/>}</P> <p>/** <br/> * This method is used to convert the number of bytes to the hexadecimal ASCII representation. <br/> * @ see: The tostring of byte in Java cannot be implemented. <br/> * @ see, but we do not have sprintf (outbuf, "% 02x", IB) <br/> */<br/> Public static string bytehex (byte Ib) {<br/> char [] digit = {'0 ', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A ', 'B', 'C', 'D', 'E', 'F'}; <br/> char [] Ob = new char [2]; <br/> ob [0] = digit [(ib> 4) & 0x0f]; <br/> ob [1] = digit [IB & 0x0f]; <br/> string S = new string (OB); <br/> return S; <br/>}</P> <p>/** <br/> * encrypt the string to be encrypted <br/> * @ see: MD5 of the string Source operation, returns the MD5 string of the string <br/> */<br/> Public static string tomd5 (string source) {<br/> MD5 MD5 = new MD5 (); <br/> return md5.getmd5ofstr (source); <br/>}</P> <p> Public static void main (string [] ARGs) {<br/> system. out. println (tomd5 ("My name is jadyer"); <br/>}< br/>}