Java implements MD5 encryption and file validation

Source: Internet
Author: User
Tags constant definition md5 encryption

MD5 Introduction:

MD5 's full name: Message-digest algorithm 5 (Information-Digest algorithm 5)

The MD5 encryption method is a hash cipher. Some mainstream programming languages have implemented MD5 encryption, so if your program or system involves checking between multiple languages, then MD5 can be one of the alternatives. However, because MD5 is encrypted using a hash function, it is not a key, that is, the MD5 can be encrypted if the plaintext is determined. But the MD5 is irreversible, can only encrypt, cannot decrypt.


MD5 Encrypted string:

public class Md5util {//Standard constructor, call Md5init function to initialize work public md5util () {md5init ();    Return    }//RFC1321 a constant definition of the standard 4*4 matrix defined in the.    static final int S11 = 7, S12 = S13, S14 = 22;    static final int S21 = 5, S22 = 9, S23 = +, S24 = 20;    static final int S31 = 4, S32 = one, S33 = +, S34 = 23;    static final int S41 = 6, S42 = ten, S43 =, S44 = 21; Definition of immutable byte array by RFC1321 standard PADDING 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    0, 0, 0, 0, 0, 0, 0, 0, 0}; MD5 3 sets of core data in the calculation process, using an array as the private long[] state = new LONG[4]; Calculation status (corresponding to a B c d) private byte[] buffer = new BYTE[64]; Allocates 64 bytes of private long[] count = new long[2];    Number of digits//The 16-ASCII string representation of the latest calculation result, representing the MD5 value public string ResultStr in the form of 16 strings; The 2-binary array of the latest calculation results, representing a total of 16 bytes, representing the 128bit form of the MD5 value public byte[] Digest= new BYTE[16];        /** * obtained two times MD5 encrypted string * * @param str * @return */public string gettwicemd5ofstring (String str) {    Return Getmd5ofstr (Getmd5ofstr (str));     } The/** * Md5_encoding class provides the primary interface function GETMD5OFSTR, which is used for data encryption transformations.     * * Call it to encrypt any string and return the result of the encryption as a string. * * @param in * @return */Public String Getmd5ofstr (string in) {Md5init ();//Initialize Md5updat E (In.getbytes (), in.length ());//Call MD5 The main calculation process md5final (); Output to digest array for (int i = 0; i <; i++) {resultstr + Bytetohex (digest[i]);//Will digest each B in the array    Yte-type data to 16 binary form of the string} return resultstr;    }//MD5 initialization function. Initializes the core variable. private void Md5init () {state[0] = 0x67452301l;//define the standard magic number defined in the state as RFC1321 state[1] = 0xefcdab89l;//define STA TE is the standard magic number defined in RFC1321 state[2] = 0x98badcfel; Defines the standard magic number defined in the state as RFC1321 state[3] = 0x10325476l; Defines the standard magic number defined in the state as RFC1321 count[0] = count[1] = 0L; Initialized to 0 ResUltstr = "";//Initialize RESULTSTR string as null for (int i = 0; I < 16;    i++) {Digest[i] = 0;//Initialization Digest array element is 0} return; }//define F G H I as 4 cardinality, i.e. 4 basic MD5 functions, for simple bitwise operation 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 call the F,g,h,i function for further transformation 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 << s) | ((int) a >>> (32-s));        Use the unsigned Right shift operator >>> A + = B when the Long data is right-shifted;    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 << s) | ((int) a >>> (32-s)); // Use the unsigned Right shift operator >>> A + = B when the Long data is right-shifted;    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));//Use the unsigned Right shift operator >>> A + = B when the Long data is right-shifted;    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 << s) |        ((int) a >>> (32-s));//Use the unsigned Right shift operator >>> A + = B when the Long data is right-shifted;    return A; }//MD5 The main calculation process, input is the binary byte string that needs to be transformed, Inputlen is the length private void md5update (byte[] input, int inputlen) {int i = 0,        index, Partlen; byte[] block = new BYTE[64]; Allocates 64 byte buffers//calculates the index value based on count.        Here the long data is shifted right using the unsigned Right shift operator >>> index = (int) (Count[0] >>> 3) & 0x3F;        if ((count[0] + = (Inputlen << 3)) < (Inputlen << 3)) {count[1]++; } COUNT[1] + = (inputlen >>> 29); Here the int data is shifted right using the unsigned Right shift operator >>> Partlen = 64-index;            Calculates the Partlen value if (Inputlen >= partlen) {md5memcpy (buffer, input, index, 0, Partlen);            Md5transform (buffer);                for (i = Partlen; i + < Inputlen; i + = +) {md5memcpy (block, input, 0, I, 64);            Md5transform (block);        } index = 0;        } else {i = 0;    } md5memcpy (buffer, input, index, I, inputlen-i);    }//Organize and fill out the output results, and put the results into the array digest.        private void Md5final () {byte[] bits = new BYTE[8];        int index, Padlen;        Encode (Bits, count, 8); index = (int) (Count[0] >>> 3) & 0x3f; Use the unsigned Right shift operator >>> Padlen = (Index < 56) When the long data is right-shifted?        (56-index): (120-index);        Md5update (PADDING, Padlen);        Md5update (Bits, 8);    Encode (Digest, State, 16); }//The block copy function of the byte array, copying the data from the input array to the starting position of Inpos, Len to the OutThe put array starts at the Outpos position.        private void md5memcpy (byte[] output, byte[] input, int outpos, int inpos, int len) {int i;        for (i = 0; i < len; i++) {output[outpos + i] = Input[inpos + i]; }}//MD5 core transform calculation program, called by the Md5update function, block is a chunked primitive byte array 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); 4 levels of intermodal//level 1th 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, 0xc1bdceeel); /* 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); /* Ten */c = FF (c, D, a, B, x[10], S13, 0xffff5bb1l); /* each */b = FF (b, C, D, A, x[11], S14, 0x895cd7bel); /* */A = FF (A, B, C, D, X[12], S11, 0x6b901122l); /* */d = FF (d, a, B, C, x[13], S12, 0xfd987193l); /* */C = FF (c, D, a, B, x[14], S13, 0xa679438el); /* */b = FF (b, C, D, A, x[15], S14, 0x49b40821l); /* 16 *///level 2nd A = GG (A, B, C, D, X[1], S21, 0xf61e2562l); /* * +/d = GG (d, a, B, C, x[6], S22, 0xc040b340l); /* */C = GG (c, D, a, B, x[11], S23, 0x265e5a51l); /* * +/b = GG (b, C, D, A, x[0], S24, 0xe9b6c7aal); /* */A = GG (A, B, C, D, X[5], S21, 0XD62F105DL); /* */d = GG (d, a, B, C, x[10], S22, 0x2441453l); /* */C = GG (c, D, a, B, x[15], S23, 0xd8a1e681l); /* * */b = GG (b, C, D, A, x[4], S24, 0xe7d3fbc8l); /* + * a = GG (A, B, C, D, X[9], S21, 0x21e1cde6l); /* */D = GG (d, a, B, C, x[14], S22, 0xc33707d6l); /* + */c = GG (c, D, a, B, x[3], S23, 0xf4d50d87l); /* */b = GG (b, C, D, A, x[8], S24, 0x455a14edl); /* * * a = GG (A, B, C, D, X[13], S21, 0xa9e3e905l); /* */d = GG (d, a, B, C, x[2], S22, 0xfcefa3f8l); /* * +/C = GG (c, D, a, B, x[7], S23, 0x676f02d9l); /* */b = GG (b, C, D, A, x[12], S24, 0x8d2a4c8al); /* 32 *///level 3rd A = HH (A, B, C, D, X[5], S31, 0xfffa3942l); /* */d = HH (d, a, B, C, x[8], S32, 0x8771f681l); /* */C = HH (c, D, a, B, x[11], S33, 0x6d9d6122l); /* * +/b = HH (b, C, D, A, x[14], S34, 0xfde5380cl); /* */A = HH (A, B, C, D, X[1], S31, 0xa4beea44l); /* PNS */d = HH (d, a, B, C, x[4], S32, 0x4bdecfa9l); /* + */c = HH (c, D, a, B, x[7], S33, 0xf6bb4b60l); /* * All-in-B = HH (b, C, D, A, x[10], S34, 0xbebfbc70l); /* + * a = HH (A, B, C, D, X[13], S31, 0x289b7ec6l); /* x */d = HH (d, a, B, C, x.[0], S32, 0xeaa127fal); /* * */C = HH (c, D, a, B, x[3], S33, 0xd4ef3085l); /* + */b = HH (b, C, D, A, x[6], S34, 0x4881d05l); /* */A = HH (A, B, C, D, X[9], S31, 0xd9d4d039l); /* */d = HH (d, a, B, C, x[12], S32, 0xe6db99e5l); /* * +/C = HH (c, D, a, B, x[15], S33, 0x1fa27cf8l); /* */b = HH (b, C, D, A, x[2], S34, 0xc4ac5665l); /* 48 *///4th Level A = II (A, B, C, D, X[0], S41, 0xf4292244l); /* */d = II (d, a, B, C, x[7], S42, 0x432aff97l); /* */C = II (c, D, a, B, x[14], S43, 0xab9423a7l); /* Wuyi */b = II (b, C, D, A, x[5], S44, 0xfc93a039l); /* */A = II (A, B, C, D, X[12], S41, 0x655b59c3l); /* +/d = II (d, a, B, C, x[3], S42, 0x8f0ccc92l); /* + */c = II (c, D, a, B, x[10], S43, 0XFFEFF47DL); /* * */b = II (b, C, D, A, x[1], S44, 0x85845dd1l); /* * * * a = II (A, B, C, D, X[8], S41, 0X6FA87E4FL); /*/+/d = II (d, a, B, C, x[15], S42, 0xfe2ce6e0l); /* + +/c = II (c, D, a, B, x[6], S43, 0xa3014314l); /* *//b = II (b, C, D, A, x[13], S44, 0x4e0811a1l); /* * a = II (A, B, C, D, X[4], S41, 0xf7537e82l); /*----*/d = II (d, a, B, C, x[11], S42, 0xbd3af235l); /* * +/C = II (c, D, a, B, x[2], S43, 0X2AD7D2BBL); /* N/b = II (b, C, D, A, x[9], S44, 0xeb86d391l);        /* 64 *//cumulative to State[0],state[1],state[2],state[3] state[0] + = A;        STATE[1] + = b;        STATE[2] + = C;    STATE[3] + = D;     }//Convert byte data to unsigned Long data private static long Bytetoul (byte b) {return b > 0? B: (b & 0x7F + 128); }//Converts data of type byte to hexadecimal ASCII character to represent private static String Bytetohex (byte in) {char[] digitstr = {' 0 ', ' 1 ',        ' 2 ', ' 3 ', ' 4 ', ' 5 ', ' 6 ', ' 7 ', ' 8 ', ' 9 ', ' A ', ' B ', ' C ', ' D ', ' E ', ' F '};        Char[] out = new char[2]; Out[0] = digitstr[(in >> 4) & 0x0F]; Take high 4-bit out[1] = digitstr[in & 0x0F]; Take a low 4 bit String s = new StRing (out);    return s;        }//The long array is split sequentially into a byte array, len private void Encode (byte[] output, long[] input, int len) {int I, J;            for (i = 0, j = 0; j < Len; i++, J + = 4) {Output[j] = (byte) (Input[i] & 0xffL);            Output[j + 1] = (byte) ((Input[i] >>> 8) & 0xffL);            Output[j + 2] = (byte) ((Input[i] >>>) & 0xffL);        Output[j + 3] = (byte) ((Input[i] >>>) & 0xffL);        }}//type array of byte array in sequence, Len private void Decode (long[] output, byte[] input, int len) {int I, J; for (i = 0, j = 0; j < Len; i++, J + + 4) {Output[i] = Bytetoul (Input[j]) | (Bytetoul (input[j + 1]) << 8) | (Bytetoul (Input[j + 2]) << 16) |        (Bytetoul (Input[j + 3]) << 24);    } return; }}

With the code above, we can use MD5 to encrypt the checksum data.


MD5 Encrypted files:

Before explaining the MD5 encrypted file, I would like to ask a question: MD5 Encrypted file is not the content of the encrypted file, and the file name or structure-independent?

Let's do a little experiment here:

1. We create a new file A.txt, content "Hello md5!", Save exit

2. Another three copies of the document, named: B.txt,c.dat,d.txt

The only difference between 3.b.txt and C.dat and A.txt is the name, and the content in D.txt is modified to "Hello MD5."

4. Encrypt these 4 files separately:

public static void Main (string[] args) {        <span style= "Font-family:courier New;" >string value = "";</span>                File File = new file ("F:/temp/zip/c.dat");        Value = md5util.getmd5byfile (file);        System.out.println (value);                File = new file ("F:/temp/zip/b.txt");        Value = md5util.getmd5byfile (file);        System.out.println (value);                File = new file ("F:/temp/zip/a.txt");        Value = md5util.getmd5byfile (file);        System.out.println (value);                File = new file ("F:/temp/zip/d.txt");        Value = md5util.getmd5byfile (file);        System.out.println (value);    }

5. The encryption results are as follows:


281d077ae77948c2c8533c01eeffd2d5281d077ae77948c2c8533c01eeffd2d5281d077ae77948c2c8533c01eeffd2d5f146f3d71763ec95d9d6c1873 927514c

The essence of the encrypted file is to encrypt the contents of the file, regardless of other factors.

Then you may ask a question, so that when we encrypt the file is not the content of the file is read into memory, and then the memory of the data in MD5 encryption? The answer is correct. But here's a question that needs to be solved: the example above is just a small file, so what if my file is large? How do we solve the problem of efficiency in encrypting large files?

The use of common Java files read and write is not enough, then there is a better way? The answer is yes, that's memory mapping. Java has provided the appropriate interface, in a good packaging mechanism, the amount of code is much reduced. The following procedure:

/**     * Encrypted files July 1, 2015 morning 12:06:37     *    /public static String getmd5byfile (file file) {        String value = Null;
   fileinputstream in = null;        try {in            = new FileInputStream (file),        } catch (FileNotFoundException E1) {            e1.printstacktrace ();        }        try {            Mappedbytebuffer bytebuffer = In.getchannel (). Map (FileChannel.MapMode.READ_ONLY, 0, File.length ());            MessageDigest MD5 = messagedigest.getinstance ("MD5");            Md5.update (bytebuffer);            BigInteger bi = new BigInteger (1, Md5.digest ());            Value = bi.tostring (+);        } catch (Exception e) {            e.printstacktrace ();        } finally {            if (null! = in) {                try {                    in.close ();                } catch (IOException e) {                    e.printstacktrace ();}}        }        return value;    }


Description:

The code used in the article originates from the experimental building.

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Java implements MD5 encryption and file validation

Related Article

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.