如何在C#和Java中生成相同的MD5 Hashcode?

我有一个在C#中生成MD5哈希的函数,如下所示:

MD5 md5 = new MD5CryptoServiceProvider(); byte[] result = md5.ComputeHash(data); StringBuilder sb = new StringBuilder(); for (int i = 0; i < result.Length; i++) { sb.Append(result[i].ToString("X2")); } return sb.ToString(); 

在java中,我的函数如下所示:

 MessageDigest m = MessageDigest.getInstance("MD5"); m.update(bytes,0,bytes.length); String hashcode = new BigInteger(1,m.digest()).toString(16); return hashcode; 

当C#代码生成:“02945C9171FBFEF0296D22B0607D522D”时,java代码生成:“5a700e63fa29a8eae77ebe0443d59239”。

有没有办法为同一个bytearray生成相同的md5哈希?

一经请求:

这是java中的testcode:

 File file = new File(System.getProperty("user.dir") + "/HashCodeTest.flv"); byte[] bytes = null; try { bytes = FileUtils.getBytesFromFile(file); } catch (IOException e) { fail(); } try { generatedHashCode = HashCode.generate(bytes); } catch (NoSuchAlgorithmException e) { fail(); } 

这是我在C#中的代码

 var blob = GetBlobByHttpPostedFile(httpPostedFile); var hashCode = Md5Factory.ConvertByteArray(blob); private static byte[] GetBlobByHttpPostedFile(HttpPostedFile httpPostedFile) { var contentLength = httpPostedFile.ContentLength; var result = new byte[contentLength]; var inputStream = httpPostedFile.InputStream; inputStream.Read(result, 0, contentLength); return result; } 

干杯

这应该没问题 – 尽管你可以通过调用来简化Java代码

 byte[] digest = m.digest(bytes); 

而不是调用update然后digest

绝对相信你在两种情况下都有相同的数据吗? 您是否可以使用相同的硬编码数据发布显示此失败的示例程序?

编辑:这是我正在考虑的那种测试。 这两个程序给出了相同的结果:

C#:

 using System; using System.Security.Cryptography; using System.Text; class Test { static void Main() { byte[] bytes = { 0x35, 0x24, 0x76, 0x12 }; MD5 md5 = new MD5CryptoServiceProvider(); byte[] result = md5.ComputeHash(bytes); StringBuilder sb = new StringBuilder(); for (int i = 0; i < result.Length; i++) { sb.Append(result[i].ToString("x2")); } Console.WriteLine(sb); } } 

Java的:

 import java.math.BigInteger; import java.security.MessageDigest; public class Test { public static void main(String[] args) throws Exception { byte[] bytes = { 0x35, 0x24, 0x76, 0x12 }; MessageDigest m = MessageDigest.getInstance("MD5"); byte[] digest = m.digest(bytes); String hash = new BigInteger(1, digest).toString(16); System.out.println(hash); } } 

嗨,我使用此代码,它的工作原理

C#代码:

  public static string ConvertStringToMD5(string ClearText) { byte[] ByteData = Encoding.ASCII.GetBytes(ClearText); //MD5 creating MD5 object. MD5 oMd5 = MD5.Create(); //Hash değerini hesaplayalım. byte[] HashData = oMd5.ComputeHash(ByteData); //convert byte array to hex format StringBuilder oSb = new StringBuilder(); for (int x = 0; x < HashData.Length; x++) { //hexadecimal string value oSb.Append(HashData[x].ToString("x2")); } 

和Java代码:

  private String getMD5Digest(byte[] buffer) { String resultHash = null; try { MessageDigest md5 = MessageDigest.getInstance("MD5"); byte[] result = new byte[md5.getDigestLength()]; md5.reset(); md5.update(buffer); result = md5.digest(); StringBuffer buf = new StringBuffer(result.length * 2); for (int i = 0; i < result.length; i++) { int intVal = result[i] & 0xff; if (intVal < 0x10) { buf.append("0"); } buf.append(Integer.toHexString(intVal)); } resultHash = buf.toString(); } catch (NoSuchAlgorithmException e) { } return resultHash; } 

我遇到了类似的问题,我们使用Java MD5 Hash来确定文件是否已被处理。 我们发现我们无法使用.NET库创建相同的哈希。 我尝试了以上所有建议,遗憾的是它不适合我。

我后来发现的解决方案是:我们不是在.NET中创建类似的函数,而是直接在.NET中调用Java函数。 有一个很棒的开源项目叫Ja.NET。 基本上我所做的是:创建一个使用相同代码创建哈希的Java类。 使用Ja.NET javac编译它。 然后使用bam将生成的Java类文件编译成DLL并在我的.NET项目中使用它。

我知道这个话题已经过时了,但我刚才遇到了同样的问题,找不到适合我的答案。 我正在为游戏编写一个修补程序,并且需要文件的md5 hashcode作为确保文件是最新的方式,但是C#和Java给了我不同的字符串,尽管文件是相同的。

这是我解决它的方式:

C#代码:

 public static string getMD5(string fullPath) { MD5 md5 = MD5.Create(); using (FileStream stream = new FileStream(fullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { byte[] hash = md5.ComputeHash(stream); StringBuilder sb = new StringBuilder(); for (int j = 0; j < hash.Length; j++) { sb.Append(hash[j].ToString("X2")); } return sb.ToString(); } } 

这将创建一个32个字符的hex字 Apache Commons DigestUtils.md5Hex(InputStream)执行相同的操作,现在唯一的不同是C#示例返回一个大写字符串,因此解决方案只是将Java程序中的哈希转换为大写字符串。

Java代码:

 public static String checkSumApacheCommons(String filePath) { String checksum = null; try { checksum = DigestUtils.md5Hex(new FileInputStream(filePath)); } catch (IOException ex) { ex.printStackTrace(System.out); } return checksum.toUpperCase(); } 

生产的哈希看起来像F674865D8A44695A2443017CFA2B0C67

希望这有助于某人。