Skip to content

Commit

Permalink
Use one-shot HashData method in .NET 9.0.
Browse files Browse the repository at this point in the history
  • Loading branch information
bgrainger committed Feb 19, 2024
1 parent f8f358d commit c93ea18
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 4 deletions.
3 changes: 2 additions & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"sdk": {
"version": "8.0.100",
"version": "9.0.100-preview",
"allowPrerelease": true,
"rollForward": "latestFeature"
}
}
15 changes: 14 additions & 1 deletion src/NGuid/GuidHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -424,9 +424,13 @@ public static Guid CreateVersion8FromName(HashAlgorithmName hashAlgorithmName, G
[SkipLocalsInit]
public static Guid CreateVersion8FromName(HashAlgorithmName hashAlgorithmName, Guid namespaceId, ReadOnlySpan<byte> name)
{
#if NET9_0_OR_GREATER
Span<byte> hashOutput = stackalloc byte[64];
#else
using var algorithm = GetHashAlgorithm(hashAlgorithmName);
Span<byte> buffer = name.Length < 500 ? stackalloc byte[16 + name.Length] : new byte[16 + name.Length];
Span<byte> hashOutput = stackalloc byte[algorithm.HashSize / 8];
#endif
Span<byte> buffer = name.Length < 500 ? stackalloc byte[16 + name.Length] : new byte[16 + name.Length];

// convert the hash space and namespace UUIDs to network order
if (!namespaceId.TryWriteBytes(buffer))
Expand All @@ -435,9 +439,16 @@ public static Guid CreateVersion8FromName(HashAlgorithmName hashAlgorithmName, G

// compute the hash of [ namespace ID, name ]
name.CopyTo(buffer[16..]);
#if NET9_0_OR_GREATER
var hashLength = CryptographicOperations.HashData(hashAlgorithmName, buffer, hashOutput);
if (hashLength == 0)
throw new InvalidOperationException("Failed to hash data");
hashOutput = hashOutput[..hashLength];
#else
var success = algorithm.TryComputeHash(buffer, hashOutput, out var bytesWritten);
if (!success || bytesWritten != hashOutput.Length)
throw new InvalidOperationException("Failed to hash data");
#endif

// the initial bytes from the hash are copied straight to the bytes of the new GUID
var newGuid = hashOutput[..16];
Expand All @@ -452,6 +463,7 @@ public static Guid CreateVersion8FromName(HashAlgorithmName hashAlgorithmName, G
}
#endif

#if !NET9_0_OR_GREATER
private static HashAlgorithm GetHashAlgorithm(HashAlgorithmName hashAlgorithmName) =>
hashAlgorithmName.Name switch
{
Expand All @@ -460,6 +472,7 @@ private static HashAlgorithm GetHashAlgorithm(HashAlgorithmName hashAlgorithmNam
"SHA512" => SHA512.Create(),
_ => throw new ArgumentException($"Unsupported hash algorithm name: {hashAlgorithmName.Name}", nameof(hashAlgorithmName)),
};
#endif

/// <summary>
/// The namespace for fully-qualified domain names (from RFC 4122, Appendix C).
Expand Down
2 changes: 1 addition & 1 deletion src/NGuid/NGuid.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>netstandard2.0;net6.0;net8.0</TargetFrameworks>
<TargetFrameworks>netstandard2.0;net6.0;net8.0;net9.0</TargetFrameworks>
<Description>Creates GUIDs according to RFC 4122 and the UUID Revision Working Draft.</Description>
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageTags>guid;uuid;rfc4122;uuidv6;uuidv7;uuidv8</PackageTags>
Expand Down
2 changes: 1 addition & 1 deletion tests/NGuid.Tests/NGuid.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net48;net8.0</TargetFrameworks>
<TargetFrameworks>net481;net8.0;net9.0</TargetFrameworks>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
<NoWarn>$(NoWarn);CS1591</NoWarn>
Expand Down

0 comments on commit c93ea18

Please sign in to comment.