MD5 哈希生成问题



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

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 

0002678D1922799CF9122B3F103975F1 and 2678D1922799CF9122B3F103975F1

我怎样才能在启动的所有 0 中获取此代码。 提前谢谢。

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

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

。但您可以使用番石榴的Strings.padStart()

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

。甚至使用 Guava 的哈希库,它返回与您的函数完全相同的字符串(我刚刚检查过):

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

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

在 Java 中,如何在保持前导零的同时将字节数组转换为十六进制数字字符串?

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

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

最新更新