tabs ↹ over ␣ ␣ ␣ spaces

by Jiří {x2} Činčura

ComputeHashAsync for SHA1

27 Jan 2014 1 mins .NET, C#, Cryptography, Multithreading/Parallelism/Asynchronous/Concurrency

Previously I blogged about creating asynchronous ComputeHash method but for SHA1Managed. But what if you want to use best implementation your platform has and you’re using SHA1.Create? Well then you need to use what’s available in public space for you.

It’s not that difficult how it might look like. You just need to work with TransformBlock and at the end with TransformFinalBlock.

public static async Task<byte[]> ComputeHashAsync(this SHA1 sha1, Stream inputStream)
{
	const int BufferSize = 4096;

	sha1.Initialize();

	var buffer = new byte[BufferSize];
	var streamLength = inputStream.Length;
	while (true)
	{
		var read = await inputStream.ReadAsync(buffer, 0, BufferSize).ConfigureAwait(false);
		if (inputStream.Position == streamLength)
		{
			sha1.TransformFinalBlock(buffer, 0, read);
			break;
		}
		sha1.TransformBlock(buffer, 0, read, default(byte[]), default(int));
	}
	return sha1.Hash;
}

Because the TransformBlock and TransformFinalBlock methods are actually defined on HashAlgorithm this might work for any derived class like i.e. MD5. But I haven’t tested it. Other classes might need also “special” calls before or after.

Profile Picture Jiří Činčura is .NET, C# and Firebird expert. He focuses on data and business layers, language constructs, parallelism, databases and performance. For almost two decades he contributes to open-source, i.e. FirebirdClient. He works as a senior software engineer for Microsoft. Frequent speaker and blogger at www.tabsoverspaces.com.