Java MessageDigest提供31位而不是32位

时间:2012-10-25 09:00:02

标签: java md5

我正在尝试使用java中的MessageDigest生成MD5哈希码。请在下面找到示例代码。我正在尝试的字符串与一些代码(KO00001)和系统日期相结合。

String s = "KO00001"+"25/10/2012";
byte[] buffer = s.getBytes();
MessageDigest md5 = MessageDigest.getInstance("MD5");
md5.update(buffer);
String str = new BigInteger(1,md5.digest()).toString(16).toUpperCase();
System.out.println(str+"    length:"+str.length());

对于像KO0000126 / 10/2012,KO0000126 / 10/2012这样的所有字符串,我的长度为32。但对于字符串“KO0000125 / 10/2012”,结果长度为31.

可能是什么原因?

3 个答案:

答案 0 :(得分:4)

答案 1 :(得分:3)

仅仅因为使用BigInteger从哈希码的字节数组表示中得到的数字比其他位置少一个。换句话说,该表示中的第一个(高)数字是零。 只是比较:

KO0000125/10/2012:
10 radix: 14105476919805249323079848858308382190    length:38
16 radix: A9C9DB4AA1D19A4126E63A7ECFD0DEE    length:31

KO0000124/10/2012:
10 radix: 132805232305710448716177011414649345991    length:39
16 radix: 63E95B7C6574B57A3FD202484D0D17C7    length:32

KO0000126/10/2012:
10 radix: 256722737628903394348650044729556126214    length:39
16 radix: C123003325E6846E04656C2F3E7ECA06    length:32

答案 2 :(得分:2)

md5.digest() 16个字节。

我怀疑你然后尝试将其输出为32个字符的十六进制字符串。

为此,你应该做类似的事情。

public static String toHexString(byte[] bytes) {
    if (bytes == null) {
        throw new IllegalArgumentException("byte array must not be null");
    }
    StringBuffer hex = new StringBuffer(bytes.length * 2);
    for (int i = 0; i < bytes.length; i++) {
        hex.append(Character.forDigit((bytes[i] & 0XF0) >> 4, 16));
        hex.append(Character.forDigit((bytes[i] & 0X0F), 16));
    }
    return hex.toString();
}

结果是d41d8cd98f00b204e9800998ecf8427e

(编辑1:或者作为Tichodroma建议:不要重新发明轮子,使用Apache Commons Codec。实际上,很多这些问题的答案是'首先检查Apache Commons')

(编辑2:不使用getBytes()而不指定编码)