源码:
import java.security.*;
public static MessageDigest digest;
public synchronized static final String hash(String data) {
if (digest == null) {
try {
//MD5算法,MD5 16位 SHA 20位
digest = MessageDigest.getInstance("MD5");
}
catch (NoSuchAlgorithmException nsae) {
System.err.println("Failed to load the MD5 MessageDigest. " +
"Jive will be unable to function normally.");
nsae.printStackTrace();
}
}
// Now, compute hash.
digest.update(data.getBytes());
//填充
return encodeHex(digest.digest());
}
/**
* Turns an array of bytes into a String representing each byte as an
* unsigned hex number.
* <p>
* Method by Santeri Paavolainen, Helsinki Finland 1996<br>
* (c) Santeri Paavolainen, Helsinki Finland 1996<br>
* Distributed under LGPL.
*
* @param bytes an array of bytes to convert to a hex-string
* @return generated hex string
*/
public static final String encodeHex(byte[] bytes) {
StringBuffer buf = new StringBuffer(bytes.length * 2);
int i;
for (i = 0; i < bytes.length; i++) {
//【1】
if (((int) bytes[i] & 0xff) < 0x10) {
//如果bytes[i]补码的低8位小于 16 buf添加0
buf.append("0");
}
//bytes[i] 的低8位,换算成16进制数,添加到buf
buf.append(Long.toString((int) bytes[i] & 0xff, 16));
}
return buf.toString();
}
/**
* Turns a hex encoded string into a byte array. It is specifically meant
* to "reverse" the toHex(byte[]) method.
*
* @param hex a hex encoded String to transform into a byte array.
* @return a byte array representing the hex String[
*/
public static final byte[] decodeHex(String hex) {
char [] chars = hex.toCharArray();
byte[] bytes = new byte[chars.length/2];
int byteCount = 0;
for (int i=0; i<chars.length; i+=2) {
byte newByte = 0x00;
newByte |= hexCharToByte(chars[i]);
newByte <<= 4;
newByte |= hexCharToByte(chars[i+1]);
bytes[byteCount] = newByte;
byteCount++;
}
return bytes;
}
/**
* Returns the the byte value of a hexadecmical char (0-f). It's assumed
* that the hexidecimal chars are lower case as appropriate.
*
* @param ch a hexedicmal character (0-f)
* @return the byte value of the character (0x00-0x0F)
*/
private static final byte hexCharToByte(char ch) {
switch(ch) {
case '0': return 0x00;
case '1': return 0x01;
case '2': return 0x02;
case '3': return 0x03;
case '4': return 0x04;
case '5': return 0x05;
case '6': return 0x06;
case '7': return 0x07;
case '8': return 0x08;
case '9': return 0x09;
case 'a': return 0x0A;
case 'b': return 0x0B;
case 'c': return 0x0C;
case 'd': return 0x0D;
case 'e': return 0x0E;
case 'f': return 0x0F;
}
return 0x00;
}
添加测试方法: 看看对字母'h'的散列函数情况
public static void main(String[] args)
{
System.out.println(MD5.hash("h"));
}
同时在【1】处 添加 作为输出分析用
System.out.println("输出bytes["+i+"]"+bytes[i]);
结果:
输出bytes[0]-44
输出bytes[1]29
输出bytes[2]-116
输出bytes[3]-39
输出bytes[4]-113
输出bytes[5]0
输出bytes[6]-78
输出bytes[7]4
输出bytes[8]-23
输出bytes[9]-128
输出bytes[10]9
输出bytes[11]-104
输出bytes[12]-20
输出bytes[13]-8
输出bytes[14]66
输出bytes[15]126
d41d8cd98f00b204e9800998ecf8427e
分析:如: -44补码 低8位 为11010100 =16*13+4=d4 ...
decodeHex(String hex)就比较容易了