StableId 1.0.0

dotnet add package StableId --version 1.0.0
                    
NuGet\Install-Package StableId -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="StableId" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="StableId" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="StableId" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add StableId --version 1.0.0
                    
#r "nuget: StableId, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package StableId@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=StableId&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=StableId&version=1.0.0
                    
Install as a Cake Tool

StableId

NuGet License

StableId is a high-performance deterministic GUID generator for .NET. Generate consistent, reproducible GUIDs from any input with exceptional performance characteristics.

Features

  • โœจ Deterministic: Same input always produces the same GUID
  • ๐Ÿš€ High Performance: Optimized for speed with minimal allocations
  • ๐Ÿ”’ Thread Safe: Safe for concurrent use
  • ๐Ÿ“ฆ Lightweight: Minimal dependencies
  • ๐ŸŽฒ UUID v5 Compatible: Uses SHA-256 hashing for deterministic generation
  • ๐ŸŽฏ Modern .NET: Built for .NET 9.0+

Quick Start

Installation

dotnet add package StableId

Basic Usage

using StableId;

// Generate GUID from string values
Guid id1 = DeterministicGuidGenerator.GenerateId("user@example.com");
Guid id2 = DeterministicGuidGenerator.GenerateId("user@example.com");
// id1 == id2 (always true)

// Generate from multiple values
Guid id3 = DeterministicGuidGenerator.GenerateId("Hello", "World", 123);
Guid id4 = DeterministicGuidGenerator.GenerateId("Hello", "World", 123);
// id3 == id4 (always true)

// Different input produces different GUID
Guid id5 = DeterministicGuidGenerator.GenerateId("Hello", "Universe");
// id5 != id3 (different input)

Smart Object Handling

The generator automatically extracts meaningful identifiers from objects using reflection:

using StableId;

// Objects with ID properties
var user = new { Id = Guid.NewGuid(), Name = "John Doe" };
var product = new { Key = 12345, ProductCode = "ABC123" };
var order = new { Identifier = 789L, Amount = 150.00m };

// Generate composite ID - uses ID properties, ignores other properties
Guid compositeId = DeterministicGuidGenerator.GenerateId(user, product, order);

// Same user with different name produces same ID (uses Id property)
var userDifferentName = new { Id = user.Id, Name = "Jane Smith" };
Guid sameId = DeterministicGuidGenerator.GenerateId(userDifferentName, product, order);
// compositeId == sameId โœ… (uses Id property, ignores Name)

ID Property Priority Order:

  1. Id
  2. Guid
  3. Key
  4. Identifier
  5. ID

Advanced Usage

using StableId;

// High-frequency generation (optimized for performance)
for (int i = 0; i < 1_000_000; i++)
{
    Guid id = DeterministicGuidGenerator.GenerateId("cache-key", i, DateTime.UtcNow.Ticks);
}

// Thread-safe concurrent usage
var tasks = Enumerable.Range(0, 1000)
    .Select(i => Task.Run(() => DeterministicGuidGenerator.GenerateId($"input-{i}")))
    .ToArray();

Guid[] results = await Task.WhenAll(tasks);

// Handle large inputs (automatic buffer management)
string largeString = new string('x', 10_000);
Guid largeId = DeterministicGuidGenerator.GenerateId(largeString);

// Complex objects with nested properties
var complexObject = new 
{
    Id = 12345,
    User = new { Name = "John", Email = "john@example.com" },
    Items = new[] { "item1", "item2", "item3" }
};
Guid complexId = DeterministicGuidGenerator.GenerateId(complexObject);

Performance Characteristics

  • Ultra-High Throughput: 4.7M+ operations per second for simple inputs
  • Sub-microsecond Latency: ~211ns average per operation
  • Excellent Scalability: Linear scaling with thread count (65M+ ops/sec on 16 threads)
  • Memory Efficient: Zero allocations for typical workloads
  • Bounded Allocations: Uses Span<T>, ArrayPool<T>, and stack allocation
  • Smart Buffering: Dynamic buffer sizing with overflow protection

Technical Details

UUID v5 Compliance

Generated GUIDs follow RFC 4122 UUID version 5 specification:

// Version bits (4 bits at position 48-51) set to 5
guidBytes[6] = (byte)((guidBytes[6] & 0x0F) | 0x50);

// Variant bits (2 bits at position 64-65) for RFC 4122 compliance
guidBytes[8] = (byte)((guidBytes[8] & 0x3F) | 0x80);

Security Features

  • SHA-256 Hashing: Cryptographically secure hash function
  • Collision Resistance: Null-byte separators prevent input collision attacks
  • Type Safety: Input validation and bounds checking
  • Recursion Protection: Maximum 10 levels of object nesting

Memory Management

  • Stack Allocation: Uses stackalloc for buffers โ‰ค 1KB
  • Array Pooling: Rents larger buffers from ArrayPool<byte>.Shared
  • Span Operations: Zero-copy operations with Span<T> and ReadOnlySpan<T>
  • Cached Reflection: Property lookup results cached with bounded cache size (1000 entries)

Error Handling

The generator includes comprehensive error handling:

// Maximum parameter validation
DeterministicGuidGenerator.GenerateId(params); // Max 100 parameters

// Null parameter protection
DeterministicGuidGenerator.GenerateId("valid", null); // Throws ArgumentException

// Buffer overflow protection
string veryLargeString = new string('x', 100_000);
Guid id = DeterministicGuidGenerator.GenerateId(veryLargeString); // Handles gracefully

// Recursion protection
var deeplyNested = /* object with 20+ levels of nesting */;
Guid id = DeterministicGuidGenerator.GenerateId(deeplyNested); // Max 10 levels, then truncates

Use Cases

  • ๐Ÿ—ƒ๏ธ Database Sharding: Consistent partition keys across services
  • ๐Ÿ’พ Caching: Deterministic cache keys for distributed caches
  • ๐Ÿ”„ Distributed Systems: Reproducible identifiers across microservices
  • ๐Ÿ“Š Data Processing: Deduplication and entity matching
  • ๐Ÿ—๏ธ Event Sourcing: Stable aggregate identifiers
  • ๐Ÿงช Testing: Predictable test data generation
  • ๐Ÿ” ETL Pipelines: Consistent record matching across data sources

Thread Safety

DeterministicGuidGenerator is fully thread-safe:

  • Static methods with no mutable state
  • Thread-safe caching with ConcurrentDictionary<T,K>
  • Atomic cache size tracking with Interlocked operations
  • No shared mutable state between operations

Requirements

  • .NET 9.0+ (uses latest performance features)
  • C# 12+ (modern language features)

Project Structure

StableId/
โ”œโ”€โ”€ src/
โ”‚   โ””โ”€โ”€ StableId/
โ”‚       โ”œโ”€โ”€ DeterministicGuidGenerator.cs    # Main implementation
โ”‚       โ””โ”€โ”€ StableId.csproj                  # Project file
โ”œโ”€โ”€ examples/
โ”‚   โ””โ”€โ”€ StableId.Examples/                   # Usage examples
โ”œโ”€โ”€ tests/
โ”‚   โ””โ”€โ”€ StableId.Tests/                      # Unit tests
โ”œโ”€โ”€ benchmarks/
โ”‚   โ””โ”€โ”€ StableId.Benchmarks/                 # Performance benchmarks
โ””โ”€โ”€ README.md

Building and Testing

# Clone the repository
git clone https://github.com/henrikroschmann/StableId.git
cd StableId

# Build the solution
dotnet build

# Run tests
dotnet test

# Run examples
dotnet run --project examples/StableId.Examples

# Run benchmarks
dotnet run --project benchmarks/StableId.Benchmarks -c Release
# Or use the convenience scripts:
# Windows: run-benchmarks.bat [core|comparison|concurrency|memory]
# PowerShell: ./run-benchmarks.ps1 [core|comparison|concurrency|memory]

Performance Benchmarks

Core Performance Results

Scenario Mean Time Allocation Throughput
Single Short String 211 ns 0 B ~4.7M ops/sec
Multiple Parameters 287 ns 0 B ~3.5M ops/sec
Complex Objects 728 ns 4 KB ~1.4M ops/sec
Very Long Strings 4.1 ฮผs 65 KB ~240K ops/sec

Comparison with Alternatives

Method Mean Time Memory Ratio vs StableId
StableId.GenerateId 211 ns 32 B 1.00x
Guid.NewGuid() 40 ns 0 B 0.19x (non-deterministic)
Manual SHA256 437 ns 328 B 2.08x
String.GetHashCode() 6 ns 0 B 0.03x (not cryptographic)

Concurrency Performance

Thread Count Operations/sec Scalability
1 Thread 4.7M ops/sec 100%
4 Threads 18.2M ops/sec 387%
8 Threads 34.8M ops/sec 741%
16 Threads 65.1M ops/sec 1,385%

Memory Efficiency

  • Zero allocations for simple scenarios
  • Minimal allocations for complex inputs
  • Stack allocation preferred for buffers โ‰ค 1KB
  • Array pooling for larger temporary buffers
  • Bounded memory usage even with very large inputs

Test Environment: .NET 9.0, Arm64 (Snapdragon X), Release build

Examples

See the examples/StableId.Examples project for comprehensive usage examples including:

  • Basic string-based ID generation
  • Smart object handling with ID property extraction
  • Performance demonstrations
  • Thread safety examples
  • Complex object scenarios

Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Add tests for new functionality
  4. Ensure all tests pass (dotnet test)
  5. Follow existing code style and patterns
  6. Submit a pull request

License

MIT License - see LICENSE file for details.

Acknowledgments

  • Inspired by RFC 4122 UUID specification (Version 5 - Name-based UUIDs)
  • Built with .NET performance best practices
  • Uses modern memory management techniques (Span<T>, ArrayPool<T>, stackalloc)

โญ Star this repo if StableId helps you build more efficient applications!

Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net9.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 976 10/28/2025