cuid2

package module
v1.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 25, 2026 License: MIT Imports: 15 Imported by: 38

README

Cuid2

Secure, collision-resistant ids optimized for horizontal scaling and performance. Next generation UUIDs.

This is a port of the JavaScript library @paralleldrive/cuid2, rewritten in Go.

For more information about Cuid2, including details about why and how, please refer to the original documentation.

Getting Started

With Go module support, you can add the following import statement to your code:

import "github.com/nrednav/cuid2"

and then run the following in the root of the repository to fetch the module:

go mod tidy

Alternatively, you can run the following command:

go get -u github.com/nrednav/cuid2

Usage

package main

import (
    "fmt"
    "github.com/nrednav/cuid2"
)

func main() {
    // Generate a Cuid with default, secure configuration
    id := cuid2.Generate()

    // or alternatively, provide your own configuration
    generate, err := cuid2.Init(
        cuid2.WithLength(32),
    )

    if err != nil {
        fmt.Println(err.Error())
    }

    // This function generates an id with a length of 32
    id = generate()

    // Validate
    cuid2.IsCuid(id)
}

Configuration

You can configure the behavior of the Cuid2 generator by providing the Init() function a series of option functions.

package main

import (
    "github.com/nrednav/cuid2"
    "sync/atomic"
)

// (Optional) create your own custom counter
type Counter struct {
    value int64
}

func NewCounter(initialCount int64) *Counter {
    return &Counter{value: initialCount}
}

func (c *Counter) Increment() int64 {
    return atomic.AddInt64(&c.value, 1)
}

func main() {
    generate, err := cuid2.Init(
        // Adjust the length of generated id, min = 2, max = 32
        cuid2.WithLength(32),

        // Provide a custom fingerprint that will be used by the id generator to help prevent
        // collisions when generating id's in a distributed system.
        cuid2.WithFingerprint("hello world"),

        // Provide a custom session counter that will be used to affect the
        // entropy of successive id generation calls
        cuid2.WithSessionCounter(NewCounter(0)),

        // Provide a custom function that generates a floating-point value between 0 and 1
        // This is useful for providing a deterministic source during testing
        cuid2.WithRandomFunc(func() float64 { return 0.1234 })
    )
}

Constants

The JavaScript reference exposes getConstants() returning { defaultLength, bigLength }. The Go port exposes the same values as package-level constants:

JavaScript getConstants() Go constant
defaultLength cuid2.DefaultIdLength
bigLength cuid2.MaxIdLength

Ordering

Generated ids embed a wall-clock timestamp, so they are only approximately ordered by creation time. A wall-clock adjustment, such as an NTP step, can make a later id sort before an earlier one. This matches the JavaScript reference.

Testing

Run the tests with:

go test

This project also includes a long-running collision and distribution stress test.

This test is excluded by default. To run the stress test, use the integration build tag:

go test -tags=integration -v -timeout=0

Here's a sample distribution for one pool of generated ids:

histogram of entropy range

Benchmarks

The id generation function can be benchmarked for varying id lengths.

To run a benchmark, use:

go test -run=XYZ -bench=. -benchtime=30s

Results:

benchmarks of id generation

Documentation

Index

Constants

View Source
const (
	DefaultIdLength int = 24
	MinIdLength     int = 2
	MaxIdLength     int = 32

	// ~22k hosts before 50% chance of initial counter collision
	MaxSessionCount int64 = 476782367

	Base36 = 36

	AlphabetSize = 26 // must equal len(alphabet)

)

Variables

This section is empty.

Functions

func Generate

func Generate() string

Generate returns a CUID using the default configuration. If initialization fails, it fails closed and a later call retries it.

func Init

func Init(options ...Option) (func() string, error)

Initializes the Cuid generator with default or user-defined config options

Returns a function that can be called to generate Cuids using the initialized config

func IsCuid

func IsCuid(cuid string) bool

Types

type Config

type Config struct {
	// A custom function that can generate a floating-point value in [0, 1)
	RandomFunc func() float64

	// A counter that will be used to affect the entropy of successive id
	// generation calls
	SessionCounter Counter

	// Length of the generated Cuid, min = 2, max = 32
	Length int

	// A unique string that will be used by the Cuid generator to help prevent
	// collisions when generating Cuids in a distributed system.
	Fingerprint string
}

type Counter

type Counter interface {
	Increment() int64
}

type Option

type Option func(*Config) error

func WithFingerprint

func WithFingerprint(fingerprint string) Option

A unique string that will be used by the id generator to help prevent collisions when generating Cuids in a distributed system.

func WithLength

func WithLength(length int) Option

Configures the length of the generated Cuid

Min Length = 2, Max Length = 32

func WithRandomFunc

func WithRandomFunc(randomFunc func() float64) Option

A custom function that will generate a random floating-point value in [0, 1)

func WithSessionCounter

func WithSessionCounter(sessionCounter Counter) Option

A custom counter that will be used to affect the entropy of successive id generation calls

type SessionCounter

type SessionCounter struct {
	// contains filtered or unexported fields
}

func NewSessionCounter

func NewSessionCounter(initialCount int64) *SessionCounter

func (*SessionCounter) Increment

func (sc *SessionCounter) Increment() int64

Increment returns the next counter value. The int64 addition wraps at the boundary, so after 2^63 increments the counter repeats its contribution; the per-call salt still carries collision resistance.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL