Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# These are supported funding model platforms

ko_fi: tensiondev
11 changes: 11 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -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"
92 changes: 92 additions & 0 deletions .github/workflows/dotnet.yml
Original file line number Diff line number Diff line change
@@ -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
56 changes: 56 additions & 0 deletions .github/workflows/package-release.yml
Original file line number Diff line number Diff line change
@@ -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

Check failure on line 50 in .github/workflows/package-release.yml

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use full commit SHA hash for this dependency.

See more on https://sonarcloud.io/project/issues?id=TensionDev_UUID.v8.CryptographicHash&issues=AaEbyaCpkaFsZPR4Wv5B&open=AaEbyaCpkaFsZPR4Wv5B&pullRequest=2
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
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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.

68 changes: 67 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,67 @@
# TensionDev.UUID.v8.CryptographicHash
# TensionDev.UUID.v8.CryptographicHash

[![.NET](https://github.com/TensionDev/UUID.v8.CryptographicHash/actions/workflows/dotnet.yml/badge.svg)](https://github.com/TensionDev/UUID.v8.CryptographicHash/actions/workflows/dotnet.yml)
[![Package Release](https://github.com/TensionDev/UUID.v8.CryptographicHash/actions/workflows/package-release.yml/badge.svg)](https://github.com/TensionDev/UUID.v8.CryptographicHash/actions/workflows/package-release.yml)
[![CodeQL](https://github.com/TensionDev/UUID.v8.CryptographicHash/actions/workflows/github-code-scanning/codeql/badge.svg)](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
```
52 changes: 52 additions & 0 deletions TensionDev.UUID.v8.CryptographicHash.Tests/SHA256Tests.cs
Original file line number Diff line number Diff line change
@@ -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);
}
}
}
52 changes: 52 additions & 0 deletions TensionDev.UUID.v8.CryptographicHash.Tests/SHA384Tests.cs
Original file line number Diff line number Diff line change
@@ -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);
}
}
}
Loading
Loading