Skip to content

Add static hash helper methods #17590

@GSPP

Description

@GSPP

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:

  1. This is more terse.
  2. 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.
  3. No way to forget resource cleanup or mess up code quality otherwise.
  4. 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;
}

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions