sleekid

package module
v2.1.3 Latest Latest
Warning

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

Go to latest
Published: Apr 16, 2025 License: MIT Imports: 5 Imported by: 0

README

sleekid

The globally unique ID for the modern software. Fully configurable. Stripe inspired.

id format

Prefix := user defined string
Timestamp := base62(unix time - 2024-01-01), T: default is 5 digits.
Random := base62(N length of random digits), N: default is 12
Checksum := base62(C length of checksum digits), C: default is 2
Total length = Prefix + T + N + C

Points

  • Human-readable prefix
  • More compact than UUID while maintaining collision resistance
    • when random digits length is 8, total length is near 16 bytes
    • shorter than UUID
  • Timestamp
    • Sortable
    • B-tree optimized with built-in timestamps
    • Extract timestamp from id
  • Built-in checksum verification
    • Detects errors with a probability of 99.97% with 2 checksum length.
  • Cryptographically random
  • URL friendly with base62 encoding
  • Fully configurable
    • prefix: any string
    • delimiter: any single character
    • timestamp length: 4 ~ 6
    • checksum length: 1 ~ 3
      • checksum token: any 64-bit integer
    • random digits length: 1 ~

Usage

import "github.com/RyosukeCla/sleekid"

// Setup generator, before using sleekid.
sleekid.Setup(sleekid.GeneratorInit{
  // Change this token on your production environment.
  // and keep it secret.
  ChecksumToken:      729823908348,

  // Optional
  RandomDigitsLength: 12,
  Delimiter:          '_',
  ChecksumLength:     2,
  TimestampLength:    5,
  TimestampOrder:     sleekid.TimestampOrderAlphabetical,
})

// Generate id.
id, err := sleekid.New("usr")

// Generate id with custom random digits length
id, err := sleekid.New("usr", sleekid.WithRandomDigits(27))

// Validate id.
sleekid.Validate(id)
sleekid.ValidateWithPrefix("usr", id)

// Get Prefix
prefix := sleekid.Prefix(id)

// Get Timestamp
timestamp := sleekid.Timestamp(id)

// Custom Generator
gen := sleekid.NewGenerator(sleekid.GeneratorInit{
  // ...
})
id, err := gen.New("usr")
gen.Validate(id)

Theory

Space Size

timestamp part with 4 ~ 6 digits.

  • Each character: 62 possibilities (0-9, a-z, A-Z)
  • 6 digits: 62^6 ≈ 56.8 quadrillion combinations

random digits part with N length

  • Each character: 62 possibilities (0-9, a-z, A-Z)
  • N characters: 62^N possible combinations
  • For N=12: 62^12 ≈ 3.22 × 10^21 combinations

total space

  • Combined unique possibilities: 62^6 * 62^N = 62^(6+N)
  • For N=12: 62^18 ≈ 1.83 × 10^32 combinations
Tamper Detection Probability
  • Tamper detection probability is 99.97% when checksum length is 2 digits
    • where 1 - 1/62^2 ≈ 0.9997
  • This helps to prevent brute-force attacks / DDoS / etc.
Length Recommendations
  • For small scale systems (<100K IDs/day): N=10
  • For medium scale systems (<10M IDs/day): N=12
  • For large scale systems (>10M IDs/day): N=14
  • For extreme scale systems (>1B IDs/day): N=16

Benchmark

$ go test -bench . -benchmem

goos: darwin
goarch: arm64
pkg: github.com/RyosukeCla/sleekid/v2
cpu: Apple M4
BenchmarkNew-10                   	 4227106	       280.4 ns/op	      56 B/op	       4 allocs/op
BenchmarkPrefix-10                	80938208	        15.29 ns/op	      16 B/op	       2 allocs/op
BenchmarkTimestamp-10             	25121528	        48.93 ns/op	       0 B/op	       0 allocs/op
BenchmarkValidate-10              	39671715	        30.22 ns/op	       2 B/op	       1 allocs/op
BenchmarkValidateWithPrefix-10    	37104268	        32.39 ns/op	       2 B/op	       1 allocs/op
BenchmarkNewUUID-10               	 6279432	       191.4 ns/op	      16 B/op	       1 allocs/op
BenchmarkNewXid-10                	35857108	        33.87 ns/op	       0 B/op	       0 allocs/op

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Prefix

func Prefix(id SleekId) string

Prefix returns the prefix of the given id.

sleekid.Prefix(id)

func Setup

func Setup(init GeneratorInit)

Setup initializes the generator.

sleekid.Setup(sleekid.GeneratorInit{
	ChecksumToken: 12345,
})

func Timestamp

func Timestamp(id SleekId) time.Time

Timestamp returns the unix time of the timestamp part.

sleekid.Timestamp(id)

func Validate

func Validate(id SleekId) bool

Validate checks if the given the timestamp and random part is valid.

sleekid.Validate(id)

func ValidateWithPrefix

func ValidateWithPrefix(prefix string, id SleekId) bool

ValidateWithPrefix checks if the given id is valid with the specific prefix..

sleekid.ValidateWithPrefix("usr", id)

Types

type GenerateOption

type GenerateOption struct {
	// RandomDigitsLength is the length of the random part of the id.
	RandomDigitsLength int
}

func WithRandomBytes

func WithRandomBytes(length int) *GenerateOption

WithRandomBytes is a helper function to set the RandomDigitsLength option.

type Generator

type Generator interface {
	// New generates a new id with the given prefix.
	//
	//	gen := NewGenerator(GeneratorInit{...})
	//	id, err := gen.New("usr")
	//	id, err := gen.New("usr", WithRandomBytes(16))
	New(prefix string, options ...*GenerateOption) (SleekId, error)

	// Prefix returns the prefix of the given id.
	//
	//	gen := NewGenerator(GeneratorInit{...})
	//	prefix := gen.Prefix(id)
	Prefix(id SleekId) string

	// Timestamp returns the unix time of the timestamp part.
	//
	//	gen := NewGenerator(GeneratorInit{...})
	//	timestamp := gen.Timestamp(id)
	Timestamp(id SleekId) time.Time

	// Validate checks if the given the timestamp and random part is valid.
	//
	//	gen := NewGenerator(GeneratorInit{...})
	//	valid := gen.Validate(id)
	Validate(id SleekId) bool

	// ValidateWithPrefix checks if the given id is valid with the specific prefix.
	//
	//	gen := NewGenerator(GeneratorInit{...})
	//	valid := gen.ValidateWithPrefix("usr", id)
	ValidateWithPrefix(prefix string, id SleekId) bool
}

func NewGenerator

func NewGenerator(init GeneratorInit) Generator

type GeneratorInit

type GeneratorInit struct {
	// delimiter is the character used to separate the prefix from the rest of the id.
	//
	// Default is "_".
	Delimiter rune

	// checksumToken is used to verify the id. Don't expose it to the public.
	//
	// Default is 4567890. Change it on your production environment.
	ChecksumToken uint64

	// ChecksumLength is the length of the checksum part of the id.
	// This will increase the precisition of the false detection rate.
	//
	// the probability of false detection is 1 - 1/62^ChecksumLength.
	// 2 is enough for most cases. It's 99.97%.
	//
	// Default is 2.
	ChecksumLength int

	// RandomDigitsLength is the length of the random part of the id.
	// Also you can customize this length when you call New() with WithRandomBytes().
	//
	// Default is 12.
	RandomDigitsLength int

	// TimestampLength is the length of the timestamp part of the id.
	//
	// Default is 5.
	// must be 4 <= TimestampLength <= 6.
	TimestampLength int

	// TimestampOrder is the order of the timestamp part of the id that sleekid generates.
	//
	// Default is Alphabetical order.
	TimestampOrder TimestampOrder
}

type SleekId

type SleekId []byte

func New

func New(prefix string, options ...*GenerateOption) (SleekId, error)

New generates a new id with the given prefix.

id, err := sleekid.New("usr")
id, err := sleekid.New("usr", sleekid.WithRandomBytes(16))

func (SleekId) String

func (id SleekId) String() string

type TimestampOrder added in v2.1.0

type TimestampOrder int
const (
	TimestampOrderAlphabetical TimestampOrder = 0
	TimestampOrderASCII        TimestampOrder = 1
)

Jump to

Keyboard shortcuts

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