简体   繁体   中英

Different MD5 between Java and C#

I want to compare MD5 hash from the same file. The file is sended as a byte[] through HTTP POST from Android, where I also calculate the hash and received from .NET server where I calculate again the hash and then want to compare them.

The problem is that for the same file I get different hashes...

Java code

FileInputStream fileInputStream = null;

byte[] bFile = new byte[(int) file.length()];

try {

    fileInputStream = new FileInputStream(file);
    fileInputStream.read(bFile);

} catch (Exception e) {
    e.printStackTrace();
}

try {
    MessageDigest md = MessageDigest.getInstance("MD5");

    int read = 0;
    while((read = fileInputStream.read(bFile)) != -1) {
        md.update(bFile, 0, read);
    }
    fileInputStream.close();

    byte[] mdBytes = md.digest();

    StringBuffer sb = new StringBuffer();
    for(int i=0; i < mdBytes.length; ++i) {
        sb.append(Integer.toString((mdBytes[i] & 0xff) + 0x100, 16).substring(1));
    }

    // generated MD5 is d41d8cd98f00b204e9800998ecf8427e


} catch (NoSuchAlgorithmException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}

C# code

using (var md5 = MD5.Create())
{
    using (var stream = File.OpenRead(filePath))
    {
        string hexString = ToHex(md5.ComputeHash(stream), false);

        // Generated MD5 is d167df114a478809ef71fb7e10c40f8c
    }
}

public string ToHex(byte[] bytes, bool upperCase)
{
    StringBuilder result = new StringBuilder(bytes.Length * 2);

    for (int i = 0; i < bytes.Length; i++)
        result.Append(bytes[i].ToString(upperCase ? "X2" : "x2"));

    return result.ToString();
}

UPDATE

I've tried to change Java code to

StringBuffer sb = new StringBuffer();
for(int i=0; i < mdBytes.length; ++i) {
    sb.append(String.format("%02x", mdBytes[i]));
}

Result is always the same...

First of all, halve your work by taking one (or more) of the many freely available tools to calculate MD5 hashes and see whether your C# or your Java code is correct (maybe both are wrong, okay :-)).

Then we'll see.

Update:

In the Java case you're reading the data into a byte array; afterwards you are using the same stream (already being EOF), thus never calling md.update .

Update 2:

So, write

[...]
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(bFile, 0 , bFile.length);
byte[] mdBytes = md.digest();
[...]

and your basically fine. Btw, interesting technique of converting a byte array to a hex string ... :-) you may want to look for a better way, though ...

读取文件流后,必须返回到流的开头才能正确计算哈希。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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