MD5哈希生成问题

时间:2012-11-02 05:21:10

标签: java md5

我正在使用以下代码为我的应用程序生成MD5哈希它编码一些字符串值然后我通过我的Web服务将这个生成的哈希发送到一些.Net代码,该代码读取我的MD5哈希并生成字符串的MD5他从DB获得的字符串然后比较它们

public static String getMD5Hash(String val) throws Exception {
        byte[] bytes = val.getBytes();

        MessageDigest m = MessageDigest.getInstance("MD5");
        byte[] digest = m.digest(bytes);
        String hash = new BigInteger(1, digest).toString(16);
        System.out.println(hash.length());
        return hash;
    }

    public static void main(String[] asd) throws Exception{
        for(int i=0;i<10;i++){
            System.out.println(getMD5Hash(i+Math.pow(10, i)+""));//for testing
            System.out.println(getMD5Hash(i+""));//for testing
        }
    }

问题是,因为我从BigInteger获得转换哈希值,有时候生成的哈希值以0开始,在这种情况下,Biginteger不考虑0,而另一方面.Net生成哈希值它使用0生成它的相同字符串,并且以这种方式字符串比较返回false,例如 哈希码我生成并发送“102678D1922799CF9122B3F103975F1”。其中.Net哈希是“0102678D1922799CF9122B3F103975F1

有时会产生类似

的代码
.Net generates  0012678D1922799CF9122B3F103975F1 and java 12678D1922799CF9122B3F103975F1 

OR

0002678D1922799CF9122B3F103975F1 and 2678D1922799CF9122B3F103975F1

如何使用start中的所有0来获取此代码。 提前谢谢。

2 个答案:

答案 0 :(得分:4)

我认为使用MessageDigest比使用填充字符串有更好的方法:

// ...
StringBuilder builder = new StringBuilder();
for (int i = hash.length(); i < 64; i++) {
  builder.append('0');
}
builder.append(hash);
return builder.toString();

...但您可以使用Guava&#39; s Strings.padStart()

// ...
return Strings.padStart(hash, 64, '0');

...甚至使用Guava's hashing library,它返回与你的函数完全相同的字符串(我刚检查过):

public static String getMD5Hash(String val) throws Exception {
  return Hashing.md5().hashBytes(val.getBytes()).toString();
}

答案 1 :(得分:3)

这个问题有一些更好的方法来生成十六进制字符串:

In Java, how do I convert a byte array to a string of hex digits while keeping leading zeros?

由于您已经在使用BigInteger,这似乎是最佳解决方案:

BigInteger bi = new BigInteger(1, digest);
String hash = String.format("%0" + (digest.length << 1) + "X", bi);