SkillAgentSearch skills...

Cuid.net

.NET implementation of collision-resistant ids

Install / Use

/learn @visus-io/Cuid.net
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

cuid.net

GitHub Workflow Status Sonar Quality Gate Sonar Coverage

Nuget Nuget Downloads GitHub

A .NET implementation of collision-resistant unique identifiers (CUIDs) designed for horizontal scalability and security in distributed environments. This library provides robust alternatives to traditional GUIDs with improved readability, sortability, and security characteristics.

For more information about CUIDs, visit the official projects: CUID and CUID2.

A command-line utility, cuidgen, is also available for leveraging CUIDs in scripting environments.

<details> <summary>Table of Contents</summary> </details>

Features

  • Two Implementations: CUIDv1 (deprecated) and CUIDv2 (recommended)
  • Collision Resistance: Cryptographically strong identifiers with negligible collision probability
  • Horizontal Scalability: Safe for distributed generation across multiple machines without coordination
  • URL-Safe Format: Base-36 encoding (0-9, a-z) for clean, readable identifiers
  • Configurable Length: CUIDv2 supports 4-32 character lengths (default: 24)
  • Type Safety: Immutable structures with full type safety and equality support
  • Framework Support: Targets .NET Standard 2.0, .NET Standard 2.1, .NET 8.0, and .NET 10.0
  • Serialization: Built-in JSON and XML serialization support for CUIDv1
  • Trimming Support: Optimized for .NET trimming in .NET 8+
  • Compiler Warnings: CUIDv1 usage emits diagnostic VISLIB0001 to encourage migration

Installation

Install cuid.net via NuGet Package Manager:

dotnet add package cuid.net

Or via the Package Manager Console:

Install-Package cuid.net

Requirements

Supported Platforms:

  • .NET 8.0+
  • .NET Core 2.0+
  • .NET Framework 4.6.1+
  • Mono 5.4+
  • Xamarin.iOS 10.14+
  • Xamarin.Mac 3.8+
  • Xamarin.Android 8.0+
  • Universal Windows Platform 10.0.16299+

Dependencies:

The library automatically includes the following runtime dependencies via NuGet:

All platforms:

  • BouncyCastle.Cryptography - SHA-3 hashing for CUIDv2
  • CommunityToolkit.Diagnostics - Guard clauses and validation

.NET Standard 2.0/2.1 only:

  • Microsoft.Bcl.HashCode - HashCode support for older frameworks
  • System.Text.Json - JSON serialization support for CUIDv1

[!NOTE] While .NET Framework 4.6.1 is the minimum supported version, .NET Framework 4.7.2+ is recommended for optimal compatibility.

Quick Start

using Visus.Cuid;

// CUIDv2 (Recommended)
Cuid2 id = new Cuid2();
Console.WriteLine(id); // o2tm13zgjtaur83duiakvgiq

// CUIDv2 with custom length
Cuid2 shortId = new Cuid2(10);
Console.WriteLine(shortId); // rolaz6ek3u

// CUIDv1 (Deprecated - emits compiler warning VISLIB0001)
Cuid legacyId = Cuid.NewCuid();
Console.WriteLine(legacyId); // cmjj07yka00016337xrs9mj24

CUIDv2 (Recommended)

[!NOTE] Cuid2 is the recommended implementation for all new projects. It provides cryptographically strong identifiers suitable for security-sensitive contexts.

Cuid2 is an immutable structure that generates collision-resistant identifiers using SHA-3 hashing. Unlike CUIDv1, it is designed with security as a primary concern and does not leak information about generation time or location.

CUIDv2 Features

  • Cryptographically Strong: Uses SHA-3 512-bit hashing via BouncyCastle
  • No Information Leakage: Cannot derive when or where the identifier was created
  • Variable Length: Supports 4-32 character identifiers (default: 24)
  • Not Sortable: Intentionally does not implement IComparable for security
  • Equality Support: Implements IEquatable<Cuid2> for comparisons
  • No Built-in Serialization: Use .ToString() for string representation

CUIDv2 Structure

CUIDv2 values use a variable-length structure with no predefined pattern. The generation process:

  1. Input Components:

    • Prefix: Single random character (a-z)
    • Timestamp: Unix timestamp in ticks
    • Counter: Session counter (initialized with cryptographic RNG, then incremented)
    • Fingerprint: Host-specific data (hostname + process ID + environment variables)
    • Random Data: Cryptographically strong random bytes (length matches requested identifier length)
  2. Hash Computation: All components except the prefix are hashed using SHA-3 512-bit

  3. Encoding: Hash is base-36 encoded, then truncated to requested length minus 1, with the random prefix prepended

Example:

o2tm13zgjtaur83duiakvgiq

CUIDv2 Usage

Basic Generation

using Visus.Cuid;

// Default length (24 characters)
Cuid2 id = new Cuid2();
Console.WriteLine(id); // o2tm13zgjtaur83duiakvgiq

// Custom length (4-32 characters)
Cuid2 shortId = new Cuid2(10);
Console.WriteLine(shortId); // v1888wvo9i

Cuid2 longId = new Cuid2(32);
Console.WriteLine(longId); // zkx5dng1v8r0dg36id29uoqt1dsndmvb

String Conversion

using Visus.Cuid;

Cuid2 id = new Cuid2();

// Explicit conversion
string idString = id.ToString();

// Implicit conversion
string implicit = id;

Equality Comparison

using Visus.Cuid;

Cuid2 id1 = new Cuid2();
Cuid2 id2 = new Cuid2();
Cuid2 id3 = id1;

// Equality operators
bool areEqual = id1 == id3;     // true
bool notEqual = id1 != id2;     // true

// Equals method
bool equals = id1.Equals(id3);  // true

// GetHashCode support for collections
HashSet<Cuid2> uniqueIds = new HashSet<Cuid2> { id1, id2, id3 };
Console.WriteLine(uniqueIds.Count); // 2

Empty/Default Values

using Visus.Cuid;

// Default value
Cuid2 defaultId = default;
Cuid2 emptyId = new Cuid2(0); // Creates empty instance

// Check for empty
bool isEmpty = string.IsNullOrEmpty(defaultId.ToString());

[!IMPORTANT] Technical Details:

  • The fingerprint size is variable (depends on hostname length and environment variables)
  • The random data size matches the requested identifier length
  • The timestamp precision is in ticks (100-nanosecond intervals), not milliseconds
  • SHA-3 is the NIST-standardized algorithm (FIPS 202), not the original Keccak submission

CUIDv2 Validation

CUIDv2 validates length during construction:

using Visus.Cuid;

try
{
    // Invalid: length must be between 4 and 32
    Cuid2 tooShort = new Cuid2(3);  // throws ArgumentOutOfRangeException
    Cuid2 tooLong = new Cuid2(33);  // throws ArgumentOutOfRangeException
}
catch (ArgumentOutOfRangeException ex)
{
    Console.WriteLine($"Invalid length: {ex.Message}");
}

// Valid lengths
Cuid2 valid1 = new Cuid2(4);   // Minimum
Cuid2 valid2 = new Cuid2(24);  // Default
Cuid2 valid3 = new Cuid2(32);  // Maximum

CUIDv1 (Deprecated)

[!CAUTION] CUIDv1 has been deprecated for security reasons. Migrate to Cuid2 for all new projects and security-sensitive applications.

[!WARNING] It is possible to derive with a degree of certainty when and where a CUIDv1 was created, making it unsuitable for security-sensitive contexts.

[!NOTE] Usage of CUIDv1 will emit the compiler warning VISLIB0001 to encourage migration to CUIDv2.

Cuid is an immutable structure designed for horizontal scaling and binary searches. It provides a sortable, "string-safe" alternative to Guid for scenarios where chronological ordering is needed and security is not a primary concern.

Security Considerations

CUIDv1 should be avoided when:

  • Security or privacy is a concern
  • Hiding generation time/location is important
  • Identifiers are exposed in URLs or public APIs
  • Compliance requires non-predictable identifiers

CUIDv1 may be acceptable for:

  • Internal identifiers in controlled environments
  • Legacy system compatibility
  • Applications where sortability is critical and security is not

CUIDv1 Structure

CUIDv1 values are composed of several data points, base-36 encoded to a fixed 25-character length:

Example:

cmjj07yka00016337xrs9mj24

| Segment | Length | Source | |------------|--------|--------------------------------------------| | c | 1 | CUIDv1 identifier pref

Related Skills

View on GitHub
GitHub Stars51
CategoryDevelopment
Updated9h ago
Forks6

Languages

C#

Security Score

100/100

Audited on Apr 2, 2026

No findings