Closed
Description
openedon Jun 12, 2016
Edit by @GrabYourPitchforks on 20 Jan 2020: Formal API proposal written at https://github.com/dotnet/corefx/issues/9369#issuecomment-576445733.
Computing a hash code currently requires this code:
byte[] hashBytes;
using (var hashAlgo = SHA256.Create())
hashBytes = hashAlgo.ComputeHash(bytes);
Or the more awkward HashAlgorithm.Create("SHA256")
.
This code is alright. It's not the end of the world. But I think it should be slimmer than that:
var hashBytes = SHA256.ComputeHash(bytes);
Benefits:
- This is more terse.
- It's an expression as opposed to a statement. That makes it more composable. It can be a subexpression for example in a LINQ query.
- No way to forget resource cleanup or mess up code quality otherwise.
SHA256.ComputeHash
can look at it's input size and dynamically pick the fastest implementation. I found the following to be optimal through testing on Windows x64:estimatedDataLength <= 512 ? new SHA1Managed() : HashAlgorithm.Create("SHA1")
. Apparently, using the Windows crypto API has quite some per-hash cost.
I request that static helper method be added to the framework. This seems like an attractive case for a community contribution.
Proposal:
Using this pattern on all of the HashAlgorithm-derived types that are not KeyedHashAlgorithm-derived types (MD5, SHA1, SHA256, SHA384, SHA512):
public partial class SHA256
{
public static byte[] Hash(byte[] source) => throw null;
public static byte[] Hash(ReadOnlySpan<byte> source) => throw null;
public static int Hash(ReadOnlySpan<byte> source, ReadOnlySpan<byte> destination) => throw null;
public static bool TryHash(ReadOnlySpan<byte> source, ReadOnlySpan<byte> destination, out int bytesWritten) => throw null;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment