I have three fields: string Title
, byte[] Body
, and byte[] Data
, from which I want to calculate a single hash as a check to be sure th
you can create a Hash over the Hash values.
MD5 md5 = System.Security.Cryptography.MD5.Create();
byte[] totalHash= md5.ComputeHash(md5.ComputeHash(part1).Concat(md5t.computeHash(part2)));
doesnt create a copy of the byte array but hashes a concatenation of the hashes.
Calling the ComputeHash function on three different values is going to create three different byte array results. Those results will then have to be combined in some way to produce a single hash. There is no way around this fact. It will create three new objects in the heap. It will compute a hash (a fairly slow operation) three times instead of just one.
I think the most performant way to do what you want is to just go ahead and copy your source values into a single byte array and take the hash of that.
You don't say why you want to avoid this approach. I think it wins in terms of simplicity and maintainability. It is the self-documenting, obvious approach. It is the most performant method. I don't really see a down-side.
There is also solution in .Net Standard and .Net Core using IncrementalHash
IncrementalHash md5 = IncrementalHash.Create(HashAlgorithmName.MD5)
// For each block:
md5.AppendData(block);
// Get the hash code
byte[] hash = md5.GetHashAndReset();
Using plain .NET, I don't think there is a way to update and MD5 hash. However, Windows has an MD5Update function defined in crypt.dll. You could use Interop to leverage this I suppose.
Otherwise, there is an implementation of a PHP equivalent in .NET c#, located here on SO: Problem porting PHP crypt() function to C#
PS: I would definitely go for the combined temp variable solution :-)
You have to combine them all in a single variable and then calculate the MD5 Hash. I don't see any shortcut there.
You see, most of solutions proposed here just try either to run multiple commands on the same line ("one liners") or implement something to "under the hood" combine your fields and then Hash...
Almost all hash algorithms are designed in a way that they can successively be fed with the data in multiple blocks. The result is the same as if the whole data was hashed at once.
Create an instance of e.g. MD5CryptoServiceProvider and call the TransformBlock Method for each block and the TransformFinalBlock Method for the last block:
MD5 md5 = new MD5CryptoServiceProvider();
// For each block:
md5.TransformBlock(block, 0, block.Length, block, 0);
// For last block:
md5.TransformFinalBlock(block, 0, block.Length);
// Get the hash code
byte[] hash = md5.Hash;