📄 md5.java
字号:
package au.net.aba.crypto.provider;
/*
* $Id: MD5.java,v 1.5 1998/10/05 05:46:52 dgh Exp $
* $Author: dgh $
*
* Copyright (C) 1996-1998 Australian Business Access Pty Ltd.
* All rights reserved.
*
* Use, modification, copying and distribution of this software is subject the
* terms and conditions of the ABA Public Licence. See the file
* "PUBLIC_LICENCE" for additional information.
*
* If you have not received a copy of the Public Licence, you must destroy all
* copies of this file immediately.
*
* $Source: /aba/CVSROOT/jdk1.1/src/au.net.aba/crypto/provider/MD5.java,v $
* $Revision: 1.5 $
* $Date: 1998/10/05 05:46:52 $
* $State: Exp $
*/
import java.security.MessageDigest;
/**
* A class that implements the RSA Data Security, Inc. MD5
* message-digest algorithm.
*/
public class MD5 extends MessageDigest
{
public final static String ident = "$Id: MD5.java,v 1.5 1998/10/05 05:46:52 dgh Exp $";
int H1, H2, H3, H4;
int count;
int[] X;
/*
* Internal input buffer for generating the message digest.
*/
private byte buffer[] = new byte[64];
/*
* Magic numbers.
*/
private static final int MAGIC1 = 0x67452301;
private static final int MAGIC2 = 0xefcdab89;
private static final int MAGIC3 = 0x98badcfe;
private static final int MAGIC4 = 0x10325476;
private static final int S11 = 7;
private static final int S12 = 12;
private static final int S13 = 17;
private static final int S14 = 22;
private static final int S21 = 5;
private static final int S22 = 9;
private static final int S23 = 14;
private static final int S24 = 20;
private static final int S31 = 4;
private static final int S32 = 11;
private static final int S33 = 16;
private static final int S34 = 23;
private static final int S41 = 6;
private static final int S42 = 10;
private static final int S43 = 15;
private static final int S44 = 21;
/**
* This constructor is used to begin a new MD5
* operation.
*/
public MD5()
{
super("MD5");
engineReset();
X = new int[16];
}
/*
* private converters
*/
/**
* do a little endian conversion from bytes to an int.
*/
private final int bytesToInt(
byte[] bytes,
int offset)
{
return ((bytes[offset + 0] << 0) & 0x000000ff) |
((bytes[offset + 1] << 8) & 0x0000ff00) |
((bytes[offset + 2] << 16) & 0x00ff0000) |
((bytes[offset + 3] << 24) & 0xff000000);
}
/**
* compute the digest and reset the engine.
*
* @return a byte array containing the message digest.
*/
protected synchronized byte[] engineDigest()
{
long bitLength;
bitLength = count << 3;
engineUpdate((byte)128);
while ((int)(count & 63) != 56)
engineUpdate((byte)0);
// convert byte buffer to int buffer.
for (int i = 0; i < 14; i++)
{
X[i] = bytesToInt(buffer, i * 4);
}
/*
* add the length in bits
*/
int half;
X[14] = (int)(bitLength & 0xffffffff);
X[15] = (int)((bitLength >>> 32) & 0xffffffff);
processBlock();
/*
* convert into byte array
*/
byte[] digest;
digest = new byte[16];
intToBytes(digest, 0, H1);
intToBytes(digest, 4, H2);
intToBytes(digest, 8, H3);
intToBytes(digest, 12, H4);
engineReset();
return digest;
}
/*
* MessageDigest methods.
*/
/**
* reset the digest back to its original state.
*/
protected void engineReset()
{
H1 = MAGIC1;
H2 = MAGIC2;
H3 = MAGIC3;
H4 = MAGIC4;
count = 0;
}
/**
* add a block of data from the array bytes to the message
* digest. The block starts offset bytes into the array, and is
* of size length.
*
* @param bytes the byte array.
* @param offset offset into the array to start from.
* @param length size of the block.
*/
protected synchronized void engineUpdate(
byte[] bytes,
int offset,
int length)
{
int index;
index = offset;
/*
* fill the current block
*/
while (!((count & 63) == 63) && length > 0)
{
engineUpdate(bytes[index++]);
length--;
}
if (length == 0)
{
return;
}
engineUpdate(bytes[index++]);
length--;
/*
* process as many whole blocks as we can
*/
while (length > 64)
{
// convert byte buffer to int buffer.
for (int i = 0; i < 16; i++)
{
X[i] = bytesToInt(bytes, index);
index += 4;
}
count += 64;
length -= 64;
processBlock();
}
/*
* process the tail fragment
*/
for (int i = 0; i != length; i++)
{
engineUpdate(bytes[i + index]);
}
}
/**
* update the digest with a single byte
*
* @param b the byte to be added.
*/
protected synchronized void engineUpdate(
byte b)
{
buffer[count & 63] = b;
if ((count & 63) == 63)
{
// convert byte buffer to int buffer.
for (int i = 0; i < 16; i++)
{
X[i] = bytesToInt(buffer, i * 4);
}
processBlock();
}
count++;
}
/*
* F, G, H and I are basic MD5 functions.
*/
private final int F(
int u,
int v,
int w)
{
return (u & v) | (~u & w);
}
/*
* FF, GG, HH, and KK transformations for rounds 1, 2, 3, and 4.
* Rotation is separate from addition to prevent recomputation.
*/
private final int FF(
int a,
int b,
int c,
int d,
int x,
int s,
int ac)
{
a += F(b, c, d) + x + ac;
a = rotateLeft(a, s);
return a + b;
}
private final int G(
int u,
int v,
int w)
{
return (u & w) | (v & ~w);
}
private final int GG(
int a,
int b,
int c,
int d,
int x,
int s,
int ac)
{
a += G(b, c, d) + x + ac;
a = rotateLeft(a, s);
return a + b;
}
private final int H(
int u,
int v,
int w)
{
return u ^ v ^ w;
}
private final int HH(
int a,
int b,
int c,
int d,
int x,
int s,
int ac)
{
a += H(b, c, d) + x + ac;
a = rotateLeft(a, s);
return a + b;
}
/**
* do a little endian conversion from an int to a byte array
*/
private final void intToBytes(
byte[] bytes,
int offset,
int val)
{
bytes[offset + 0] = (byte)((val >>> 0) & 0xff);
bytes[offset + 1] = (byte)((val >>> 8) & 0xff);
bytes[offset + 2] = (byte)((val >>> 16) & 0xff);
bytes[offset + 3] = (byte)((val >>> 24) & 0xff);
}
private final int K(
int u,
int v,
int w)
{
return v ^ (u | ~w);
}
private final int KK(
int a,
int b,
int c,
int d,
int x,
int s,
int ac)
{
a += K(b, c, d) + x + ac;
a = rotateLeft(a, s);
return a + b;
}
/*
* MD5 basic transformation. Transforms state
* based on block.
*/
private final synchronized void processBlock()
{
int a = H1;
int b = H2;
int c = H3;
int d = H4;
// Round 1
a = FF(a, b, c, d, X[ 0], S11, 0xd76aa478); // 1
d = FF(d, a, b, c, X[ 1], S12, 0xe8c7b756); // 2
c = FF(c, d, a, b, X[ 2], S13, 0x242070db); // 3
b = FF(b, c, d, a, X[ 3], S14, 0xc1bdceee); // 4
a = FF(a, b, c, d, X[ 4], S11, 0xf57c0faf); // 5
d = FF(d, a, b, c, X[ 5], S12, 0x4787c62a); // 6
c = FF(c, d, a, b, X[ 6], S13, 0xa8304613); // 7
b = FF(b, c, d, a, X[ 7], S14, 0xfd469501); // 8
a = FF(a, b, c, d, X[ 8], S11, 0x698098d8); // 9
d = FF(d, a, b, c, X[ 9], S12, 0x8b44f7af); // 10
c = FF(c, d, a, b, X[10], S13, 0xffff5bb1); // 11
b = FF(b, c, d, a, X[11], S14, 0x895cd7be); // 12
a = FF(a, b, c, d, X[12], S11, 0x6b901122); // 13
d = FF(d, a, b, c, X[13], S12, 0xfd987193); // 14
c = FF(c, d, a, b, X[14], S13, 0xa679438e); // 15
b = FF(b, c, d, a, X[15], S14, 0x49b40821); // 16
// Round 2
a = GG(a, b, c, d, X[ 1], S21, 0xf61e2562); // 17
d = GG(d, a, b, c, X[ 6], S22, 0xc040b340); // 18
c = GG(c, d, a, b, X[11], S23, 0x265e5a51); // 19
b = GG(b, c, d, a, X[ 0], S24, 0xe9b6c7aa); // 20
a = GG(a, b, c, d, X[ 5], S21, 0xd62f105d); // 21
d = GG(d, a, b, c, X[10], S22, 0x02441453); // 22
c = GG(c, d, a, b, X[15], S23, 0xd8a1e681); // 23
b = GG(b, c, d, a, X[ 4], S24, 0xe7d3fbc8); // 24
a = GG(a, b, c, d, X[ 9], S21, 0x21e1cde6); // 25
d = GG(d, a, b, c, X[14], S22, 0xc33707d6); // 26
c = GG(c, d, a, b, X[ 3], S23, 0xf4d50d87); // 27
b = GG(b, c, d, a, X[ 8], S24, 0x455a14ed); // 28
a = GG(a, b, c, d, X[13], S21, 0xa9e3e905); // 29
d = GG(d, a, b, c, X[ 2], S22, 0xfcefa3f8); // 30
c = GG(c, d, a, b, X[ 7], S23, 0x676f02d9); // 31
b = GG(b, c, d, a, X[12], S24, 0x8d2a4c8a); // 32
// Round 3
a = HH(a, b, c, d, X[ 5], S31, 0xfffa3942); // 33
d = HH(d, a, b, c, X[ 8], S32, 0x8771f681); // 34
c = HH(c, d, a, b, X[11], S33, 0x6d9d6122); // 35
b = HH(b, c, d, a, X[14], S34, 0xfde5380c); // 36
a = HH(a, b, c, d, X[ 1], S31, 0xa4beea44); // 37
d = HH(d, a, b, c, X[ 4], S32, 0x4bdecfa9); // 38
c = HH(c, d, a, b, X[ 7], S33, 0xf6bb4b60); // 39
b = HH(b, c, d, a, X[10], S34, 0xbebfbc70); // 40
a = HH(a, b, c, d, X[13], S31, 0x289b7ec6); // 41
d = HH(d, a, b, c, X[ 0], S32, 0xeaa127fa); // 42
c = HH(c, d, a, b, X[ 3], S33, 0xd4ef3085); // 43
b = HH(b, c, d, a, X[ 6], S34, 0x04881d05); // 44
a = HH(a, b, c, d, X[ 9], S31, 0xd9d4d039); // 45
d = HH(d, a, b, c, X[12], S32, 0xe6db99e5); // 46
c = HH(c, d, a, b, X[15], S33, 0x1fa27cf8); // 47
b = HH(b, c, d, a, X[ 2], S34, 0xc4ac5665); // 48
// Round 4
a = KK(a, b, c, d, X[ 0], S41, 0xf4292244); // 49
d = KK(d, a, b, c, X[ 7], S42, 0x432aff97); // 50
c = KK(c, d, a, b, X[14], S43, 0xab9423a7); // 51
b = KK(b, c, d, a, X[ 5], S44, 0xfc93a039); // 52
a = KK(a, b, c, d, X[12], S41, 0x655b59c3); // 53
d = KK(d, a, b, c, X[ 3], S42, 0x8f0ccc92); // 54
c = KK(c, d, a, b, X[10], S43, 0xffeff47d); // 55
b = KK(b, c, d, a, X[ 1], S44, 0x85845dd1); // 56
a = KK(a, b, c, d, X[ 8], S41, 0x6fa87e4f); // 57
d = KK(d, a, b, c, X[15], S42, 0xfe2ce6e0); // 58
c = KK(c, d, a, b, X[ 6], S43, 0xa3014314); // 59
b = KK(b, c, d, a, X[13], S44, 0x4e0811a1); // 60
a = KK(a, b, c, d, X[ 4], S41, 0xf7537e82); // 61
d = KK(d, a, b, c, X[11], S42, 0xbd3af235); // 62
c = KK(c, d, a, b, X[ 2], S43, 0x2ad7d2bb); // 63
b = KK(b, c, d, a, X[ 9], S44, 0xeb86d391); // 64
H1 += a;
H2 += b;
H3 += c;
H4 += d;
// Zeroize possibly sensitive information.
for (int i = 0; i < X.length; i++)
{
X[i] = 0;
}
}
/*
* rotateLeft rotates x left n bits.
* this assumes that an int is 32 bits wide.
*/
private final int rotateLeft(
int x,
int n)
{
return (x << n) | (x >>> (32 - n));
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -