[英]Issue with MD5 hash generation
我正在使用以下代碼為我的應用程序生成MD5哈希,它對一些字符串值進行編碼,然后通過Web服務將此生成的哈希發送到某個.Net代碼,該代碼讀取我的MD5哈希並生成字符串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,例如哈希碼i生成並發送“ 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();
...但是您可以使用Guava的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);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.