0

我正在尝试使用 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。

可能是什么原因?

4

3 回答 3

4

我推荐org.apache.commons.codec.digest.DigestUtils.md5Hex()这个任务。

于 2012-10-25T09:10:24.363 回答
3

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

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
于 2012-10-25T09:19:37.900 回答
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() 而不指定编码)

于 2012-10-25T09:12:35.113 回答