From c35301f78b43ff0e299b539e87aee7f9cb57a133 Mon Sep 17 00:00:00 2001
From: amsga <49681949+amsga@users.noreply.github.com>
Date: Thu, 8 Oct 2026 21:48:09 +0800
Subject: [PATCH] Added SHA256.cs for SHA-256 implementation for UUIDv8. Added
SHA384.cs for SHA-384 implementation for UUIDv8. Added SHA512.cs for SHA-512
implementation for UUIDv8.
---
.github/FUNDING.yml | 3 +
.github/dependabot.yml | 11 +++
.github/workflows/dotnet.yml | 92 +++++++++++++++++++
.github/workflows/package-release.yml | 56 +++++++++++
CHANGELOG.md | 15 +++
README.md | 68 +++++++++++++-
.../SHA256Tests.cs | 52 +++++++++++
.../SHA384Tests.cs | 52 +++++++++++
.../SHA512Tests.cs | 52 +++++++++++
...Dev.UUID.v8.CryptographicHash.Tests.csproj | 24 +++++
TensionDev.UUID.v8.CryptographicHash.slnx | 1 +
.../Class1.cs | 9 --
.../SHA256.cs | 85 +++++++++++++++++
.../SHA384.cs | 87 ++++++++++++++++++
.../SHA512.cs | 87 ++++++++++++++++++
...ensionDev.UUID.v8.CryptographicHash.csproj | 32 ++++++-
16 files changed, 715 insertions(+), 11 deletions(-)
create mode 100644 .github/FUNDING.yml
create mode 100644 .github/dependabot.yml
create mode 100644 .github/workflows/dotnet.yml
create mode 100644 .github/workflows/package-release.yml
create mode 100644 CHANGELOG.md
create mode 100644 TensionDev.UUID.v8.CryptographicHash.Tests/SHA256Tests.cs
create mode 100644 TensionDev.UUID.v8.CryptographicHash.Tests/SHA384Tests.cs
create mode 100644 TensionDev.UUID.v8.CryptographicHash.Tests/SHA512Tests.cs
create mode 100644 TensionDev.UUID.v8.CryptographicHash.Tests/TensionDev.UUID.v8.CryptographicHash.Tests.csproj
delete mode 100644 TensionDev.UUID.v8.CryptographicHash/Class1.cs
create mode 100644 TensionDev.UUID.v8.CryptographicHash/SHA256.cs
create mode 100644 TensionDev.UUID.v8.CryptographicHash/SHA384.cs
create mode 100644 TensionDev.UUID.v8.CryptographicHash/SHA512.cs
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 0000000..13f9d90
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,3 @@
+# These are supported funding model platforms
+
+ko_fi: tensiondev
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000..5072385
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,11 @@
+# To get started with Dependabot version updates, you'll need to specify which
+# package ecosystems to update and where the package manifests are located.
+# Please see the documentation for all configuration options:
+# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
+
+version: 2
+updates:
+ - package-ecosystem: "nuget" # See documentation for possible values
+ directory: "/" # Location of package manifests
+ schedule:
+ interval: "monthly"
diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml
new file mode 100644
index 0000000..e66596c
--- /dev/null
+++ b/.github/workflows/dotnet.yml
@@ -0,0 +1,92 @@
+name: .NET
+
+on:
+ push:
+ branches: [ "**" ]
+ pull_request:
+ branches: [ "master" ]
+
+jobs:
+ build:
+
+ runs-on: windows-latest
+
+ strategy:
+ matrix:
+ dotnet: [ '10.0.x' ]
+ name: .NET ${{ matrix.dotnet }}
+
+ steps:
+ - name: Set up JDK 25
+ uses: actions/setup-java@v6
+ with:
+ java-version: 25
+ distribution: 'zulu' # Alternative distribution options are available.
+ - uses: actions/checkout@v7
+ with:
+ fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
+ - name: Setup .NET
+ uses: actions/setup-dotnet@v6
+ with:
+ dotnet-version: ${{ matrix.dotnet }}
+ - name: Cache SonarQube Cloud packages
+ uses: actions/cache@v5
+ with:
+ path: ~\sonar\cache
+ key: ${{ runner.os }}-sonar
+ restore-keys: ${{ runner.os }}-sonar
+ - name: Cache SonarQube Cloud scanner
+ id: cache-sonar-scanner
+ uses: actions/cache@v5
+ with:
+ path: .\.sonar\scanner
+ key: ${{ runner.os }}-sonar-scanner
+ restore-keys: ${{ runner.os }}-sonar-scanner
+ - name: Install SonarQube Cloud scanner
+ if: steps.cache-sonar-scanner.outputs.cache-hit != 'true'
+ shell: powershell
+ run: |
+ New-Item -Path .\.sonar\scanner -ItemType Directory
+ dotnet tool update dotnet-sonarscanner --tool-path .\.sonar\scanner
+ - name: Restore dependencies
+ run: dotnet restore
+ - name: SonarCloudPrepare
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
+ SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
+ run: .\.sonar\scanner\dotnet-sonarscanner begin /k:"TensionDev_UUID.v8.CryptographicHash" /o:"tensiondev" /d:sonar.token="${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.scanner.scanAll=false /d:sonar.cs.opencover.reportsPaths=**/coverage.opencover.xml
+ - name: Build
+ run: dotnet build --no-restore
+ - name: Test
+ run: dotnet run --project TensionDev.UUID.v8.CryptographicHash.Tests/TensionDev.UUID.v8.CryptographicHash.Tests.csproj --no-build -- --coverlet --coverlet-output-format opencover
+ - name: SonarCloudAnalyze
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
+ SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
+ run: .\.sonar\scanner\dotnet-sonarscanner end /d:sonar.token="${{ secrets.SONAR_TOKEN }}"
+
+ test:
+
+ strategy:
+ matrix:
+ dotnet: [ '10.0.x' ]
+ os: [macos-latest, ubuntu-latest, windows-latest]
+
+ runs-on: ${{ matrix.os }}
+
+ name: .NET ${{ matrix.dotnet }} on ${{ matrix.os }}
+
+ steps:
+ - uses: actions/checkout@v7
+ with:
+ fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
+ - name: Setup .NET
+ uses: actions/setup-dotnet@v6
+ with:
+ dotnet-version: ${{ matrix.dotnet }}
+ - name: Restore dependencies
+ run: dotnet restore
+ - name: Build
+ run: dotnet build --no-restore
+ - name: Test
+ run: dotnet run --project TensionDev.UUID.v8.CryptographicHash.Tests/TensionDev.UUID.v8.CryptographicHash.Tests.csproj --no-build -- --coverlet --coverlet-output-format opencover
diff --git a/.github/workflows/package-release.yml b/.github/workflows/package-release.yml
new file mode 100644
index 0000000..0153d82
--- /dev/null
+++ b/.github/workflows/package-release.yml
@@ -0,0 +1,56 @@
+# This is a basic workflow to help you get started with Actions
+
+name: Package Release
+
+# Controls when the workflow will run
+on:
+ # Triggers the workflow on push events but only for the tags
+ push:
+ tags:
+ - v[0-9]+.[0-9]+.[0-9]+
+ - v[0-9]+.[0-9]+.[0-9]+-alpha
+ - v[0-9]+.[0-9]+.[0-9]+-beta
+
+# A workflow run is made up of one or more jobs that can run sequentially or in parallel
+jobs:
+ # This workflow contains a single job called "build"
+ build:
+ permissions:
+ id-token: write # enable GitHub OIDC token issuance for this job
+
+ # The type of runner that the job will run on
+ runs-on: ubuntu-latest
+
+ # Steps represent a sequence of tasks that will be executed as part of the job
+ steps:
+ # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
+ - uses: actions/checkout@v4
+
+ - name: Setup .NET 10
+ uses: actions/setup-dotnet@v6
+ with:
+ dotnet-version: 10.0.x
+ source-url: https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json
+ env:
+ NUGET_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
+
+ - name: Restore dependencies
+ run: dotnet restore
+
+ - name: Build
+ run: dotnet build --no-restore
+
+ - name: Build Release
+ run: dotnet build --configuration Release --no-restore
+
+ - name: Pack
+ run: dotnet pack --configuration Release
+
+ - name: NuGet login (OIDC ? temp API key)
+ uses: NuGet/login@v1
+ id: login
+ with:
+ user: ${{ secrets.NUGET_USER }} # Recommended: use a secret like ${{ secrets.NUGET_USER }} for your nuget.org username (profile name), NOT your email address
+
+ - name: Push NuGet
+ run: dotnet nuget push "TensionDev.UUID.v8.CryptographicHash/bin/Release/*.nupkg" --source https://api.nuget.org/v3/index.json --api-key ${{steps.login.outputs.NUGET_API_KEY}} --no-symbols --skip-duplicate
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..42a3780
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,15 @@
+# TensionDev.UUID.v8.CryptographicHash
+
+# Changelog
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
+and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## [Unreleased]
+
+### Added
+- Added SHA-256 implementation for UUIDv8.
+- Added SHA-384 implementation for UUIDv8.
+- Added SHA-512 implementation for UUIDv8.
+
diff --git a/README.md b/README.md
index 8b868c6..d516bda 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,67 @@
-# TensionDev.UUID.v8.CryptographicHash
\ No newline at end of file
+# TensionDev.UUID.v8.CryptographicHash
+
+[](https://github.com/TensionDev/UUID.v8.CryptographicHash/actions/workflows/dotnet.yml)
+[](https://github.com/TensionDev/UUID.v8.CryptographicHash/actions/workflows/package-release.yml)
+[](https://github.com/TensionDev/UUID.v8.CryptographicHash/actions/workflows/github-code-scanning/codeql)
+
+TensionDev.UUID.v8.CryptographicHash is a .NET library extending [TensionDev.UUID](https://github.com/TensionDev/UUID) with support for name-based UUID Version 8 using Cryptographic Hash Algorithms.
+This project references the following documents for implementation.
+- [Universally unique identifier - Wikipedia](https://en.wikipedia.org/wiki/Universally_unique_identifier)
+- [rfc9562](https://datatracker.ietf.org/doc/html/rfc9562)
+
+---
+
+## Features
+
+- Support for three SHA-2 hash algorithms:
+ - SHA-256
+ - SHA-384
+ - SHA-512
+- Strict RFC compliance for parsing and validation
+
+---
+
+## Installation
+```bash
+dotnet add package TensionDev.UUID.v8.CryptographicHash
+```
+
+---
+
+## Usage Examples
+
+### Generate SHA-256 UUID v8
+```csharp
+using TensionDev.UUID.v8.CryptographicHash;
+
+// Generate a UUID using DNS namespace with SHA-256
+Uuid uuid = SHA256.NewUUIDv8(UUIDNamespace.DNS, "www.contoso.com");
+Console.WriteLine(uuid); // Example: 0b3e79a4-6f85-825a-a65d-fc78495c9381
+```
+
+### Generate SHA-384 UUID v8
+```csharp
+using TensionDev.UUID.v8.CryptographicHash;
+
+// Generate a UUID using URL namespace with SHA-384
+Uuid uuid = SHA384.NewUUIDv8(UUIDNamespace.URL, "https://www.contoso.com");
+Console.WriteLine(uuid); // Example: 1a261a04-809b-8b96-b370-2cdfaa8dfb9c
+```
+
+### Generate SHA-512 UUID v8
+```csharp
+using TensionDev.UUID.v8.CryptographicHash;
+
+// Generate a UUID using OID namespace with SHA-512
+Uuid uuid = SHA512.NewUUIDv8(UUIDNamespace.OID, "1.0.3166.1");
+Console.WriteLine(uuid); // c05c49a2-ae23-83e9-913e-34dfe2751dc5
+```
+
+### Verify UUID Version 8
+```csharp
+using TensionDev.UUID.v8.CryptographicHash;
+
+Uuid uuid = SHA512.NewUUIDv8(UUIDNamespace.X500, "/c=us/o=Sun/ou=People/cn=Rosanna Lee");
+bool isValid = SHA512.IsUUIDv8(uuid);
+Console.WriteLine(isValid); // true
+```
diff --git a/TensionDev.UUID.v8.CryptographicHash.Tests/SHA256Tests.cs b/TensionDev.UUID.v8.CryptographicHash.Tests/SHA256Tests.cs
new file mode 100644
index 0000000..531c109
--- /dev/null
+++ b/TensionDev.UUID.v8.CryptographicHash.Tests/SHA256Tests.cs
@@ -0,0 +1,52 @@
+using System;
+using Xunit;
+
+namespace TensionDev.UUID.v8.CryptographicHash.Tests
+{
+ public class SHA256Tests
+ {
+ [Fact]
+ public void TestNewUUIDv8_DNS()
+ {
+ Uuid expectedGuid = new Uuid("44032eb4-74f7-8141-8763-95bcb31a00fe");
+
+ String name = "www.contoso.com";
+ Uuid guid = SHA256.NewUUIDv8(UUIDNamespace.DNS, name);
+
+ Assert.Equal(expectedGuid, guid);
+ }
+
+ [Fact]
+ public void TestNewUUIDv8_URL()
+ {
+ Uuid expectedGuid = new Uuid("226d46ea-9b85-8da3-8817-276aca4b261b");
+
+ String name = "https://www.contoso.com";
+ Uuid guid = SHA256.NewUUIDv8(UUIDNamespace.URL, name);
+
+ Assert.Equal(expectedGuid, guid);
+ }
+
+ [Fact]
+ public void TestNewUUIDv8_OID()
+ {
+ Uuid expectedGuid = new Uuid("10356f08-bb14-84f2-a235-eecb59b45093");
+
+ String name = "1.0.3166.1";
+ Uuid guid = SHA256.NewUUIDv8(UUIDNamespace.OID, name);
+
+ Assert.Equal(expectedGuid, guid);
+ }
+
+ [Fact]
+ public void TestNewUUIDv8_X500()
+ {
+ Uuid expectedGuid = new Uuid("c507cb8a-ae3d-8fb6-955c-e896f927db96");
+
+ String name = "/c=us/o=Sun/ou=People/cn=Rosanna Lee";
+ Uuid guid = SHA256.NewUUIDv8(UUIDNamespace.X500, name);
+
+ Assert.Equal(expectedGuid, guid);
+ }
+ }
+}
diff --git a/TensionDev.UUID.v8.CryptographicHash.Tests/SHA384Tests.cs b/TensionDev.UUID.v8.CryptographicHash.Tests/SHA384Tests.cs
new file mode 100644
index 0000000..2eafdce
--- /dev/null
+++ b/TensionDev.UUID.v8.CryptographicHash.Tests/SHA384Tests.cs
@@ -0,0 +1,52 @@
+using System;
+using Xunit;
+
+namespace TensionDev.UUID.v8.CryptographicHash.Tests
+{
+ public class SHA384Tests
+ {
+ [Fact]
+ public void TestNewUUIDv8_DNS()
+ {
+ Uuid expectedGuid = new Uuid("57017b32-f32a-8b1a-8353-90371a43ff48");
+
+ String name = "www.contoso.com";
+ Uuid guid = SHA384.NewUUIDv8(UUIDNamespace.DNS, name);
+
+ Assert.Equal(expectedGuid, guid);
+ }
+
+ [Fact]
+ public void TestNewUUIDv8_URL()
+ {
+ Uuid expectedGuid = new Uuid("1a261a04-809b-8b96-b370-2cdfaa8dfb9c");
+
+ String name = "https://www.contoso.com";
+ Uuid guid = SHA384.NewUUIDv8(UUIDNamespace.URL, name);
+
+ Assert.Equal(expectedGuid, guid);
+ }
+
+ [Fact]
+ public void TestNewUUIDv8_OID()
+ {
+ Uuid expectedGuid = new Uuid("0cfd5769-6138-888d-8c4f-0f677985e8b1");
+
+ String name = "1.0.3166.1";
+ Uuid guid = SHA384.NewUUIDv8(UUIDNamespace.OID, name);
+
+ Assert.Equal(expectedGuid, guid);
+ }
+
+ [Fact]
+ public void TestNewUUIDv8_X500()
+ {
+ Uuid expectedGuid = new Uuid("f72b2828-e8ef-8d98-96e5-a6504cf3d31f");
+
+ String name = "/c=us/o=Sun/ou=People/cn=Rosanna Lee";
+ Uuid guid = SHA384.NewUUIDv8(UUIDNamespace.X500, name);
+
+ Assert.Equal(expectedGuid, guid);
+ }
+ }
+}
diff --git a/TensionDev.UUID.v8.CryptographicHash.Tests/SHA512Tests.cs b/TensionDev.UUID.v8.CryptographicHash.Tests/SHA512Tests.cs
new file mode 100644
index 0000000..04560d5
--- /dev/null
+++ b/TensionDev.UUID.v8.CryptographicHash.Tests/SHA512Tests.cs
@@ -0,0 +1,52 @@
+using System;
+using Xunit;
+
+namespace TensionDev.UUID.v8.CryptographicHash.Tests
+{
+ public class SHA512Tests
+ {
+ [Fact]
+ public void TestNewUUIDv8_DNS()
+ {
+ Uuid expectedGuid = new Uuid("1f58b34f-76c4-8de7-bde4-153328cbb927");
+
+ String name = "www.contoso.com";
+ Uuid guid = SHA512.NewUUIDv8(UUIDNamespace.DNS, name);
+
+ Assert.Equal(expectedGuid, guid);
+ }
+
+ [Fact]
+ public void TestNewUUIDv8_URL()
+ {
+ Uuid expectedGuid = new Uuid("f1e5150c-0997-8d69-b643-95dc044a901d");
+
+ String name = "https://www.contoso.com";
+ Uuid guid = SHA512.NewUUIDv8(UUIDNamespace.URL, name);
+
+ Assert.Equal(expectedGuid, guid);
+ }
+
+ [Fact]
+ public void TestNewUUIDv8_OID()
+ {
+ Uuid expectedGuid = new Uuid("c05c49a2-ae23-83e9-913e-34dfe2751dc5");
+
+ String name = "1.0.3166.1";
+ Uuid guid = SHA512.NewUUIDv8(UUIDNamespace.OID, name);
+
+ Assert.Equal(expectedGuid, guid);
+ }
+
+ [Fact]
+ public void TestNewUUIDv8_X500()
+ {
+ Uuid expectedGuid = new Uuid("3a1bcb1a-c7b9-86de-afc0-a715e399649c");
+
+ String name = "/c=us/o=Sun/ou=People/cn=Rosanna Lee";
+ Uuid guid = SHA512.NewUUIDv8(UUIDNamespace.X500, name);
+
+ Assert.Equal(expectedGuid, guid);
+ }
+ }
+}
diff --git a/TensionDev.UUID.v8.CryptographicHash.Tests/TensionDev.UUID.v8.CryptographicHash.Tests.csproj b/TensionDev.UUID.v8.CryptographicHash.Tests/TensionDev.UUID.v8.CryptographicHash.Tests.csproj
new file mode 100644
index 0000000..26bd4cc
--- /dev/null
+++ b/TensionDev.UUID.v8.CryptographicHash.Tests/TensionDev.UUID.v8.CryptographicHash.Tests.csproj
@@ -0,0 +1,24 @@
+
+
+
+ net10.0
+
+ false
+ true
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
diff --git a/TensionDev.UUID.v8.CryptographicHash.slnx b/TensionDev.UUID.v8.CryptographicHash.slnx
index 1ed350c..5c1db22 100644
--- a/TensionDev.UUID.v8.CryptographicHash.slnx
+++ b/TensionDev.UUID.v8.CryptographicHash.slnx
@@ -1,3 +1,4 @@
+
diff --git a/TensionDev.UUID.v8.CryptographicHash/Class1.cs b/TensionDev.UUID.v8.CryptographicHash/Class1.cs
deleted file mode 100644
index 7530638..0000000
--- a/TensionDev.UUID.v8.CryptographicHash/Class1.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using System;
-
-namespace TensionDev.UUID.v8.CryptographicHash
-{
- public class Class1
- {
-
- }
-}
diff --git a/TensionDev.UUID.v8.CryptographicHash/SHA256.cs b/TensionDev.UUID.v8.CryptographicHash/SHA256.cs
new file mode 100644
index 0000000..269726b
--- /dev/null
+++ b/TensionDev.UUID.v8.CryptographicHash/SHA256.cs
@@ -0,0 +1,85 @@
+// SPDX-License-Identifier: Apache-2.0
+//
+// Copyright 2021 - 2026 TensionDev
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+using System;
+using System.Text;
+
+namespace TensionDev.UUID.v8.CryptographicHash
+{
+ ///
+ /// Class Library to generate Universally Unique Identifier (UUID) / Globally Unique Identifier (GUID) based on Version 8 using SHA-256 namespace name-based.
+ ///
+ public static class SHA256
+ {
+ ///
+ /// Initialises a new GUID/UUID based on Version 8 using SHA-256 namespace name-based
+ ///
+ /// A new Uuid object
+ public static Uuid NewUUIDv8(Uuid nameSpace, String name)
+ {
+ Byte[] nsArray = nameSpace.ToByteArray();
+ Byte[] nArray = Encoding.UTF8.GetBytes(name);
+
+ Byte[] buffer = new Byte[nsArray.Length + nArray.Length];
+ Buffer.BlockCopy(nsArray, 0, buffer, 0, nsArray.Length);
+ Buffer.BlockCopy(nArray, 0, buffer, nsArray.Length, nArray.Length);
+
+ Byte[] hash;
+#if NET6_0_OR_GREATER
+ hash = System.Security.Cryptography.SHA256.HashData(buffer);
+#else
+ using (System.Security.Cryptography.SHA256 sha256 = System.Security.Cryptography.SHA256.Create())
+ {
+ hash = sha256.ComputeHash(buffer);
+ }
+#endif
+
+ Byte[] hex = new Byte[16];
+
+ hex[0] = hash[0];
+ hex[1] = hash[1];
+ hex[2] = hash[2];
+ hex[3] = hash[3];
+
+ hex[4] = hash[4];
+ hex[5] = hash[5];
+
+ hex[6] = (Byte)((hash[6] & 0x0F) + 0x80);
+ hex[7] = hash[7];
+
+ hex[8] = (Byte)((hash[8] & 0x3F) + 0x80);
+ hex[9] = hash[9];
+
+ hex[10] = hash[10];
+ hex[11] = hash[11];
+ hex[12] = hash[12];
+ hex[13] = hash[13];
+ hex[14] = hash[14];
+ hex[15] = hash[15];
+
+ Uuid Id = new Uuid(hex);
+
+ return Id;
+ }
+
+ ///
+ /// Returns true if the Uuid specified is Version 8.
+ ///
+ /// The Uuid to be tested.
+ /// Returns true if the Uuid specified is Version 8.
+ public static bool IsUUIDv8(Uuid uuid) => TensionDev.UUID.UUIDv8.IsUUIDv8(uuid);
+ }
+}
diff --git a/TensionDev.UUID.v8.CryptographicHash/SHA384.cs b/TensionDev.UUID.v8.CryptographicHash/SHA384.cs
new file mode 100644
index 0000000..cf6b145
--- /dev/null
+++ b/TensionDev.UUID.v8.CryptographicHash/SHA384.cs
@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: Apache-2.0
+//
+// Copyright 2021 - 2026 TensionDev
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+using System;
+using System.Text;
+
+namespace TensionDev.UUID.v8.CryptographicHash
+{
+ ///
+ /// Class Library to generate Universally Unique Identifier (UUID) / Globally Unique Identifier (GUID) based on Version 8 using SHA-384 namespace name-based.
+ ///
+ public static class SHA384
+ {
+ ///
+ /// Initialises a new GUID/UUID based on Version 8 using SHA-384 namespace name-based.
+ ///
+ /// The namespace UUID to use for hashing.
+ /// The name string to hash with the namespace.
+ /// A new Uuid object
+ public static Uuid NewUUIDv8(Uuid nameSpace, String name)
+ {
+ Byte[] nsArray = nameSpace.ToByteArray();
+ Byte[] nArray = Encoding.UTF8.GetBytes(name);
+
+ Byte[] buffer = new Byte[nsArray.Length + nArray.Length];
+ Buffer.BlockCopy(nsArray, 0, buffer, 0, nsArray.Length);
+ Buffer.BlockCopy(nArray, 0, buffer, nsArray.Length, nArray.Length);
+
+ Byte[] hash;
+#if NET6_0_OR_GREATER
+ hash = System.Security.Cryptography.SHA384.HashData(buffer);
+#else
+ using (System.Security.Cryptography.SHA384 sha384 = System.Security.Cryptography.SHA384.Create())
+ {
+ hash = sha384.ComputeHash(buffer);
+ }
+#endif
+
+ Byte[] hex = new Byte[16];
+
+ hex[0] = hash[0];
+ hex[1] = hash[1];
+ hex[2] = hash[2];
+ hex[3] = hash[3];
+
+ hex[4] = hash[4];
+ hex[5] = hash[5];
+
+ hex[6] = (Byte)((hash[6] & 0x0F) + 0x80);
+ hex[7] = hash[7];
+
+ hex[8] = (Byte)((hash[8] & 0x3F) + 0x80);
+ hex[9] = hash[9];
+
+ hex[10] = hash[10];
+ hex[11] = hash[11];
+ hex[12] = hash[12];
+ hex[13] = hash[13];
+ hex[14] = hash[14];
+ hex[15] = hash[15];
+
+ Uuid Id = new Uuid(hex);
+
+ return Id;
+ }
+
+ ///
+ /// Returns true if the Uuid specified is Version 8.
+ ///
+ /// The Uuid to be tested.
+ /// Returns true if the Uuid specified is Version 8.
+ public static bool IsUUIDv8(Uuid uuid) => TensionDev.UUID.UUIDv8.IsUUIDv8(uuid);
+ }
+}
diff --git a/TensionDev.UUID.v8.CryptographicHash/SHA512.cs b/TensionDev.UUID.v8.CryptographicHash/SHA512.cs
new file mode 100644
index 0000000..939ddda
--- /dev/null
+++ b/TensionDev.UUID.v8.CryptographicHash/SHA512.cs
@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: Apache-2.0
+//
+// Copyright 2021 - 2026 TensionDev
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+using System;
+using System.Text;
+
+namespace TensionDev.UUID.v8.CryptographicHash
+{
+ ///
+ /// Class Library to generate Universally Unique Identifier (UUID) / Globally Unique Identifier (GUID) based on Version 8 using SHA-512 namespace name-based.
+ ///
+ public static class SHA512
+ {
+ ///
+ /// Initialises a new GUID/UUID based on Version 8 using SHA-512 namespace name-based.
+ ///
+ /// The namespace UUID to use for hashing.
+ /// The name string to hash with the namespace.
+ /// A new Uuid object
+ public static Uuid NewUUIDv8(Uuid nameSpace, String name)
+ {
+ Byte[] nsArray = nameSpace.ToByteArray();
+ Byte[] nArray = Encoding.UTF8.GetBytes(name);
+
+ Byte[] buffer = new Byte[nsArray.Length + nArray.Length];
+ Buffer.BlockCopy(nsArray, 0, buffer, 0, nsArray.Length);
+ Buffer.BlockCopy(nArray, 0, buffer, nsArray.Length, nArray.Length);
+
+ Byte[] hash;
+#if NET6_0_OR_GREATER
+ hash = System.Security.Cryptography.SHA512.HashData(buffer);
+#else
+ using (System.Security.Cryptography.SHA512 sha512 = System.Security.Cryptography.SHA512.Create())
+ {
+ hash = sha512.ComputeHash(buffer);
+ }
+#endif
+
+ Byte[] hex = new Byte[16];
+
+ hex[0] = hash[0];
+ hex[1] = hash[1];
+ hex[2] = hash[2];
+ hex[3] = hash[3];
+
+ hex[4] = hash[4];
+ hex[5] = hash[5];
+
+ hex[6] = (Byte)((hash[6] & 0x0F) + 0x80);
+ hex[7] = hash[7];
+
+ hex[8] = (Byte)((hash[8] & 0x3F) + 0x80);
+ hex[9] = hash[9];
+
+ hex[10] = hash[10];
+ hex[11] = hash[11];
+ hex[12] = hash[12];
+ hex[13] = hash[13];
+ hex[14] = hash[14];
+ hex[15] = hash[15];
+
+ Uuid Id = new Uuid(hex);
+
+ return Id;
+ }
+
+ ///
+ /// Returns true if the Uuid specified is Version 8.
+ ///
+ /// The Uuid to be tested.
+ /// Returns true if the Uuid specified is Version 8.
+ public static bool IsUUIDv8(Uuid uuid) => TensionDev.UUID.UUIDv8.IsUUIDv8(uuid);
+ }
+}
diff --git a/TensionDev.UUID.v8.CryptographicHash/TensionDev.UUID.v8.CryptographicHash.csproj b/TensionDev.UUID.v8.CryptographicHash/TensionDev.UUID.v8.CryptographicHash.csproj
index dbdcea4..792e584 100644
--- a/TensionDev.UUID.v8.CryptographicHash/TensionDev.UUID.v8.CryptographicHash.csproj
+++ b/TensionDev.UUID.v8.CryptographicHash/TensionDev.UUID.v8.CryptographicHash.csproj
@@ -1,7 +1,37 @@
- netstandard2.0
+ netstandard2.0;netcoreapp3.1;net6.0;net8.0;net10.0
+ all
+ True
+ true
+ true
+ 0.1.0-alpha.1
+ TensionDev amsga
+ TensionDev
+ TensionDev.UUID.v8.CryptographicHash is a .NET library that supports UUID version v8 with strict RFC compliance.
+ Copyright (c) TensionDev 2021 - 2026
+ Apache-2.0
+ https://github.com/TensionDev/UUID.v8.CryptographicHash
+ https://github.com/TensionDev/UUID.v8.CryptographicHash
+ git
+ UUID GUID
+ Initial Release
+ en-SG
+ true
+ snupkg
+ README.md
+
+
+ True
+ \
+
+
+
+
+
+
+