繁体   English   中英

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

[英]How can you generate the same MD5 Hashcode in C# and Java?

我有一个在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个字符的十六进制字 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

希望这有助于某人。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM