📄 md5.java
字号:
package net.propero.rdp.crypto;
/**
* This class implements the MD5 message digest algorithm.
* <p>
* <b>BUG</b>: The update method is missing.
* <p>
* <b>References:</b>
* <ol>
* <li> Ronald L. Rivest,
* "<a href="http://www.roxen.com/rfc/rfc1321.html">
* The MD5 Message-Digest Algorithm</a>",
* IETF RFC-1321 (informational).
* <li> Bruce Schneier,
* "Section 18.5 MD5,"
* <cite>Applied Cryptography, 2nd edition</cite>,
* John Wiley & Sons, 1996
* <p>
* </ol>
* <p>
* <b>Copyright</b> © 1995-1997
* <a href="http://www.systemics.com/">Systemics Ltd</a> on behalf of the
* <a href="http://www.systemics.com/docs/cryptix/">Cryptix Development Team</a>.
* <br>All rights reserved.
* <p>
* <b>$Revision: 1.6 $</b>
* @author Systemics Ltd
* @author David Hopwood
* @since Cryptix 2.2
*/
public final class MD5
extends BlockMessageDigest
implements Cloneable
{
// MD5 constants and variables
//...........................................................................
/** Length of the final hash (in bytes). */
private static final int HASH_LENGTH = 16;
/** Length of a block (the number of bytes hashed in every transform). */
private static final int DATA_LENGTH = 64;
private int[] data;
private int[] digest;
private byte[] tmp;
/** Returns the length of the hash (in bytes). */
protected int engineGetDigestLength() { return HASH_LENGTH; }
/** Returns the length of the data (in bytes) hashed in every transform. */
protected int engineGetDataLength() { return DATA_LENGTH; }
/**
* The public constructor.
*/
public MD5()
{
super("MD5");
java_init();
engineReset();
}
private void java_init() {
digest = new int[HASH_LENGTH/4];
data = new int[DATA_LENGTH/4];
tmp = new byte[DATA_LENGTH];
}
/**
* This constructor is here to implement cloneability of this class.
*/
private MD5 (MD5 md) {
this();
data = (int[])md.data.clone();
digest = (int[])md.digest.clone();
tmp = (byte[])md.tmp.clone();
}
/**
* Returns a copy of this MD object.
*/
public Object clone() { return new MD5(this); }
/**
* Initializes (resets) the message digest.
*/
public void engineReset()
{
super.engineReset();
java_reset();
}
private void java_reset() {
digest[0] = 0x67452301;
digest[1] = 0xEFCDAB89;
digest[2] = 0x98BADCFE;
digest[3] = 0x10325476;
}
/**
* Adds data to the message digest.
*
* @param data The data to be added.
* @param offset The start of the data in the array.
* @param length The amount of data to add.
*/
protected void engineTransform(byte[] in)
{
java_transform(in);
}
private void java_transform(byte[] in)
{
byte2int(in, 0, data, 0, DATA_LENGTH/4);
transform(data);
}
/**
* Returns the digest of the data added and resets the digest.
* @return the digest of all the data added to the message digest as a byte array.
*/
public byte[] engineDigest(byte[] in, int length)
{
byte b[] = java_digest(in, length);
engineReset();
return b;
}
private byte[] java_digest(byte[] in, int pos)
{
if (pos != 0) System.arraycopy(in, 0, tmp, 0, pos);
tmp[pos++] = -128; // (byte)0x80;
if (pos > DATA_LENGTH - 8)
{
while (pos < DATA_LENGTH)
tmp[pos++] = 0;
byte2int(tmp, 0, data, 0, DATA_LENGTH/4);
transform(data);
pos = 0;
}
while (pos < DATA_LENGTH - 8)
tmp[pos++] = 0;
byte2int(tmp, 0, data, 0, (DATA_LENGTH/4)-2);
int bc = bitcount();
data[14] = bc;
data[15] = 0;
transform(data);
byte buf[] = new byte[HASH_LENGTH];
// Little endian
int off = 0;
for (int i = 0; i < HASH_LENGTH/4; ++i) {
int d = digest[i];
buf[off++] = (byte) d;
buf[off++] = (byte) (d>>>8);
buf[off++] = (byte) (d>>>16);
buf[off++] = (byte) (d>>>24);
}
return buf;
}
// MD5 transform routines
//...........................................................................
static protected int F(int x,int y,int z) { return (z ^ (x & (y^z))); }
static protected int G(int x,int y,int z) { return (y ^ (z & (x^y))); }
static protected int H(int x,int y,int z) { return (x ^ y ^ z); }
static protected int I(int x,int y,int z) { return (y ^ (x | ~z)); }
static protected int FF(int a,int b,int c,int d,int k,int s,int t)
{
a += k+t+F(b,c,d);
a = (a << s | a >>> -s);
return a+b;
}
static protected int GG(int a,int b,int c,int d,int k,int s,int t)
{
a += k+t+G(b,c,d);
a = (a << s | a >>> -s);
return a+b;
}
static protected int HH(int a,int b,int c,int d,int k,int s,int t)
{
a += k+t+H(b,c,d);
a = (a << s | a >>> -s);
return a+b;
}
static protected int II(int a,int b,int c,int d,int k,int s,int t)
{
a += k+t+I(b,c,d);
a = (a << s | a >>> -s);
return a+b;
}
protected void transform (int M[])
{
int a,b,c,d;
a = digest[0];
b = digest[1];
c = digest[2];
d = digest[3];
a = FF(a,b,c,d,M[ 0], 7,0xd76aa478);
d = FF(d,a,b,c,M[ 1],12,0xe8c7b756);
c = FF(c,d,a,b,M[ 2],17,0x242070db);
b = FF(b,c,d,a,M[ 3],22,0xc1bdceee);
a = FF(a,b,c,d,M[ 4], 7,0xf57c0faf);
d = FF(d,a,b,c,M[ 5],12,0x4787c62a);
c = FF(c,d,a,b,M[ 6],17,0xa8304613);
b = FF(b,c,d,a,M[ 7],22,0xfd469501);
a = FF(a,b,c,d,M[ 8], 7,0x698098d8);
d = FF(d,a,b,c,M[ 9],12,0x8b44f7af);
c = FF(c,d,a,b,M[10],17,0xffff5bb1);
b = FF(b,c,d,a,M[11],22,0x895cd7be);
a = FF(a,b,c,d,M[12], 7,0x6b901122);
d = FF(d,a,b,c,M[13],12,0xfd987193);
c = FF(c,d,a,b,M[14],17,0xa679438e);
b = FF(b,c,d,a,M[15],22,0x49b40821);
a = GG(a,b,c,d,M[ 1], 5,0xf61e2562);
d = GG(d,a,b,c,M[ 6], 9,0xc040b340);
c = GG(c,d,a,b,M[11],14,0x265e5a51);
b = GG(b,c,d,a,M[ 0],20,0xe9b6c7aa);
a = GG(a,b,c,d,M[ 5], 5,0xd62f105d);
d = GG(d,a,b,c,M[10], 9,0x02441453);
c = GG(c,d,a,b,M[15],14,0xd8a1e681);
b = GG(b,c,d,a,M[ 4],20,0xe7d3fbc8);
a = GG(a,b,c,d,M[ 9], 5,0x21e1cde6);
d = GG(d,a,b,c,M[14], 9,0xc33707d6);
c = GG(c,d,a,b,M[ 3],14,0xf4d50d87);
b = GG(b,c,d,a,M[ 8],20,0x455a14ed);
a = GG(a,b,c,d,M[13], 5,0xa9e3e905);
d = GG(d,a,b,c,M[ 2], 9,0xfcefa3f8);
c = GG(c,d,a,b,M[ 7],14,0x676f02d9);
b = GG(b,c,d,a,M[12],20,0x8d2a4c8a);
a = HH(a,b,c,d,M[ 5], 4,0xfffa3942);
d = HH(d,a,b,c,M[ 8],11,0x8771f681);
c = HH(c,d,a,b,M[11],16,0x6d9d6122);
b = HH(b,c,d,a,M[14],23,0xfde5380c);
a = HH(a,b,c,d,M[ 1], 4,0xa4beea44);
d = HH(d,a,b,c,M[ 4],11,0x4bdecfa9);
c = HH(c,d,a,b,M[ 7],16,0xf6bb4b60);
b = HH(b,c,d,a,M[10],23,0xbebfbc70);
a = HH(a,b,c,d,M[13], 4,0x289b7ec6);
d = HH(d,a,b,c,M[ 0],11,0xeaa127fa);
c = HH(c,d,a,b,M[ 3],16,0xd4ef3085);
b = HH(b,c,d,a,M[ 6],23,0x04881d05);
a = HH(a,b,c,d,M[ 9], 4,0xd9d4d039);
d = HH(d,a,b,c,M[12],11,0xe6db99e5);
c = HH(c,d,a,b,M[15],16,0x1fa27cf8);
b = HH(b,c,d,a,M[ 2],23,0xc4ac5665);
a = II(a,b,c,d,M[ 0], 6,0xf4292244);
d = II(d,a,b,c,M[ 7],10,0x432aff97);
c = II(c,d,a,b,M[14],15,0xab9423a7);
b = II(b,c,d,a,M[ 5],21,0xfc93a039);
a = II(a,b,c,d,M[12], 6,0x655b59c3);
d = II(d,a,b,c,M[ 3],10,0x8f0ccc92);
c = II(c,d,a,b,M[10],15,0xffeff47d);
b = II(b,c,d,a,M[ 1],21,0x85845dd1);
a = II(a,b,c,d,M[ 8], 6,0x6fa87e4f);
d = II(d,a,b,c,M[15],10,0xfe2ce6e0);
c = II(c,d,a,b,M[ 6],15,0xa3014314);
b = II(b,c,d,a,M[13],21,0x4e0811a1);
a = II(a,b,c,d,M[ 4], 6,0xf7537e82);
d = II(d,a,b,c,M[11],10,0xbd3af235);
c = II(c,d,a,b,M[ 2],15,0x2ad7d2bb);
b = II(b,c,d,a,M[ 9],21,0xeb86d391);
digest[0] += a;
digest[1] += b;
digest[2] += c;
digest[3] += d;
}
// why was this public?
// Note: parameter order changed to be consistent with System.arraycopy.
private static void byte2int(byte[] src, int srcOffset,
int[] dst, int dstOffset, int length)
{
while (length-- > 0)
{
// Little endian
dst[dstOffset++] = (src[srcOffset++] & 0xFF) |
((src[srcOffset++] & 0xFF) << 8) |
((src[srcOffset++] & 0xFF) << 16) |
((src[srcOffset++] & 0xFF) << 24);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -