源代碼
本文只給出了具體的實現,至於算法原理請參考相關文章。
注:本算法系數參考百度百科:MD5。
算法經過簡化後,如下所示。
public class MD5 {
private static final int[] mix = { 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613,
0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, 0x21e1cde6,
0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681,
0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 0x289b7ec6, 0xeaa127fa, 0xd4ef3085,
0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82,
0xbd3af235, 0x2ad7d2bb, 0xeb86d391 };
private static final int[] shift = { 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5, 9, 14, 20, 5, 9, 14,
20, 5, 9, 14, 20, 5, 9, 14, 20, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10, 15, 21,
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 };
public static String hash(String source) {
int a, b, c, d, f, g, v;
// string to byte array
int[] bts = new int[(((source.length() + 8) / 64) + 1) * 16];
for (int i = 0; i < source.length(); i++)
bts[i >> 2] |= source.charAt(i) << ((i % 4) * 8);
bts[source.length() >> 2] |= 0x80 << ((source.length() % 4) * 8);
bts[bts.length - 2] = source.length() * 8;
int[] temps = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 };
for (int i = 0; i < bts.length / 16; i++) {
int[] num = new int[16];
for (int j = 0; j < 16; j++)
num[j] = bts[i * 16 + j];
a = temps[0];
b = temps[1];
c = temps[2];
d = temps[3];
for (int k = 0; k < 64; k++) {
if (k < 16) {
f = (b & c) | ((~b) & d);
g = k;
} else if (k < 32) {
f = (d & b) | ((~d) & c);
g = (5 * k + 1) % 16;
} else if (k < 48) {
f = b ^ c ^ d;
g = (3 * k + 5) % 16;
} else {
f = c ^ (b | (~d));
g = (7 * k) % 16;
}
int tmp = d;
d = c;
c = b;
v = a + f + mix[k] + num[g];
b += (v << shift[k]) | (v >>> (32 - shift[k]));
a = tmp;
}
temps[0] += a;
temps[1] += b;
temps[2] += c;
temps[3] += d;
}
StringBuilder sb = new StringBuilder();
for (int j = 0; j < temps.length; j++)
for (int i = 0; i < 4; i++)
sb.append(String.format("%2s", Integer.toHexString(((temps[i] >> i * 8) % (1 << 8)) & 0xff)));
return sb.toString();
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
String input = "hello" + i;
System.out.printf("MD5(%s) --> %s\n", input, MD5.hash(input));
}
}
}
執行後的結果爲:
MD5(hello0) --> 4fd621724fd621724fd621724fd62172
MD5(hello1) --> 20d71fd220d71fd220d71fd220d71fd2
MD5(hello2) --> 6e7316546e7316546e7316546e731654
MD5(hello3) --> 7c9319ae7c9319ae7c9319ae7c9319ae
MD5(hello4) --> a7e1dab6a7e1dab6a7e1dab6a7e1dab6
MD5(hello5) --> eb 0db17eb 0db17eb 0db17eb 0db17
MD5(hello6) --> 57479a2a57479a2a57479a2a57479a2a
MD5(hello7) --> 2b10ee582b10ee582b10ee582b10ee58
MD5(hello8) --> f7bf892af7bf892af7bf892af7bf892a
MD5(hello9) --> 1c3eb7f11c3eb7f11c3eb7f11c3eb7f1