JAVA Implementation of the MD5 Algorithm

Source: Internet
Author: User

// 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/>}

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.