Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Hashing multiple byte array blocks

Tags:

c#

hash

md5

I am trying to hash a file by reading 1024 bytes from a FileStream in a loop and using TransformBlock function. I need this to understand the mechanics of hashing multiple byte arrays into one hash. This would allow me to hash not only files, but also folders. I used this stackoverflow question: Hashing multiple byte[]'s together into a single hash with C#? and this msdn example: http://msdn.microsoft.com/en-us/library/system.security.cryptography.hashalgorithm.transformblock.aspx

Here is the code I have now:

public static byte[] createFileMD5(string path){
    MD5 md5 = MD5.Create();
    FileStream fs = File.OpenRead(path);
    byte[] buf = new byte[1024];
    byte[] newbuf = new byte[1024];

    int num; int newnum;

    num = fs.Read(buf,0,buf.Length);
    while ((newnum = fs.Read(newbuf, 0, newbuf.Length))>0)
    {
        md5.TransformBlock(buf, 0, buf.Length, buf, 0);
        num = newnum;
        buf = newbuf;
    }

    md5.TransformFinalBlock(buf, 0, num);

    return md5.Hash;
}

Unfortunately the hash which it calculates doesnt correspond to the one which I calculated using fciv.

Just to be sure: hexing algorithm which I use on the returned byte array:

    public static string byteArrayToString(byte[] ba)
    {
        StringBuilder hex = new StringBuilder(ba.Length * 2);
        foreach (byte b in ba)
            hex.AppendFormat("{0:x2}", b);
        return hex.ToString();
    }
like image 575
black Avatar asked Jul 03 '26 04:07

black


1 Answers

The length you pass to TransformBlock is wrong for the last block (unless the file size is a multiple of the buffer size). You need to pass the actual number of bytes read from the file:

md5.TransformBlock(buf, 0, newnum, buf, 0);

Also, I'm not sure why you use newbuf... the original buffer is used only for the first block, then you use newbuf for all subsequent blocks. There is no reason to use a second buffer here. For reference, here's the code I use to compute the hash of a file:

            using (var stream = File.OpenRead(path))
            {
                var md5 = MD5.Create();
                var buffer = new byte[8192];
                int read;
                while ((read = stream.Read(buffer, 0, buffer.Length)) > 0)
                {
                    md5.TransformBlock(buffer, 0, read, buffer, 0);
                }
                md5.TransformFinalBlock(buffer, 0, 0);

                ...
            }
like image 129
Thomas Levesque Avatar answered Jul 05 '26 17:07

Thomas Levesque



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!