shortid Go Package

repository·master·Indexed 21 days ago

https://github.com/teris-io/shortid

A Go package for generating short, unique, non-sequential, and URL-friendly IDs designed for high-concurrency environments. It supports custom generators with configurable worker IDs (up to 32), alphabets, and seeds, guaranteeing unique IDs from 2016 until 2050. The library provides package-level functions like Generate() and MustGenerate(), as well as the ability to create custom Shortid instances via shortid.New().

Tokens
1.6K
Snippets
8
Records
10
Agent score
26%

What's inside shortid

  1. Understand shortid ID structure and length

    master

    Short IDs are composed of three encoded pieces of information:

    1. Milliseconds since epoch: The first 8 symbols (Epoch starts at 1/1/2016).
    2. Worker ID: The 9th symbol.
    3. Concurrent counter: Only added if multiple IDs are generated within the same millisecond, spanning the remaining symbols.

    Expected Lengths:

    • Standard: 9 symbols (at a rate of 1 ID per millisecond).
    • High Load: Occasionally reaches 11 symbols (at a rate of a few thousand IDs per millisecond).
    • Extreme Load: May exceed 11 symbols during continuous full-throttle generation on high-performance hardware.
  2. Uniqueness and collision guarantees

    master

    The shortid package guarantees unique, non-colliding IDs for the period between 1/1/2016 and 1/1/2050, provided that:

    • You use the same worker ID within a single application.
    • Application restarts take longer than 1 millisecond.
    • You support up to 32 unique workers, each providing a unique sequence from the others.
  3. Initialize and reuse a custom generator

    master

    For better performance and control, it is recommended to initialize a specific generator for a given worker and reuse it. You can use the instance directly or set it as the package default using shortid.SetDefault(sid).

    shortid.New takes three arguments:

    1. workerId: An integer representing the worker (supports up to 32 workers).
    2. alphabet: The character set to use (e.g., shortid.DefaultABC).
    3. seed: An integer seed for the generator.
    sid, err := shortid.New(1, shortid.DefaultABC, 2342)
    
    // Option 1: Use the instance directly
    fmt.Printf(sid.Generate())
    fmt.Printf(sid.Generate())
    
    // Option 2: Set as the package default
    shortid.SetDefault(sid)
    fmt.Printf(shortid.Generate())
    fmt.Printf(shortid.Generate())
  4. Generate short IDs using the default generator

    master

    The simplest way to generate unique, non-sequential, and URL-friendly IDs is to use the package-level shortid.Generate() function. This uses the default internal generator.

    fmt.Printf(shortid.Generate())
    fmt.Printf(shortid.Generate())
  5. Create a custom Shortid generator

    master

    Use shortid.New() to create a new Shortid instance with specific configurations. This is essential for distributed systems to prevent collisions.

    Parameters:

    • worker (uint8): A unique identifier for the process/worker. Must be in the range [0, 31]. Different workers should use different numbers to ensure uniqueness across distributed processes.
    • alphabet (string): A string of exactly 64 unique characters used for encoding. The default is DefaultABC.
    • seed (uint64): A seed used to shuffle the alphabet. This should be identical across all workers if they are intended to use the same alphabet mapping.
    import "github.com/teris-io/teris-io/shortid"
    
    // worker 5, custom alphabet, seed 12345
    sid, err := shortid.New(5, "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-", 12345)
    if err != nil {
    	// handle error
    }
    
    id, err := sid.Generate()
  6. Create a custom alphabet with NewAbc

    master

    The Abc type represents a shuffled alphabet used for encoding. You can create a custom one using shortid.NewAbc(alphabet, seed).

    Requirements:

    • The alphabet string must contain exactly 64 unique characters.
    • The seed is used to shuffle the alphabet.
    import "github.com/teris-io/teris-io/shortid"
    
    // alphabet must be 64 unique chars
    abc, err := shortid.NewAbc("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-", 42)
    if err != nil {
    	// handle error
    }
  7. Generate a short ID using the default generator

    master

    Use shortid.Generate() to create a unique, non-sequential, and URL-friendly ID using the package's default configuration (worker 0, default alphabet, and seed 1).

    import "github.com/teris-io/teris-io/shortid"
    
    id, err := shortid.Generate()
    if err != nil {
    	// handle error
    }
  8. Configure the default shortid generator

    master

    You can overwrite the global default generator used by Generate() and MustGenerate() by calling shortid.SetDefault(sid). This allows you to configure a single Shortid instance and use it globally throughout your application.

    import "github.com/teris-io/teris-io/shortid"
    
    sid, _ := shortid.New(1, shortid.DefaultABC, 999)
    shortid.SetDefault(sid)
    
    // Now this uses the custom sid
    id, _ := shortid.Generate()
  9. Encode values using an Abc instance

    master

    Use the Encode method on an Abc instance to convert a value into a slice of runes. This allows you to control the randomness and length of the encoded output.

    Parameters:

    • val (uint): The value to encode.
    • nsymbols (uint): The desired number of symbols. If 0, the size is automatically computed.
    • digits (uint): Controls randomness.
      • 4: High randomness (up to 16 values per symbol).
      • 5: Medium randomness (up to 32 values per symbol).
      • 6: No randomness (exactly 1 symbol per 64 values).

    Note: digits must be in the range [4, 6].

    // Using an Abc instance to encode the value 100 into 5 symbols with medium randomness
    runes, err := abc.Encode(100, 5, 5)
  10. Generate a short ID using MustGenerate

    master

    Use shortid.MustGenerate() if you prefer the function to panic instead of returning an error when generation fails. This is typically used in initialization or when failure is considered a fatal state.

    import "github.com/teris-io/teris-io/shortid"
    
    id := shortid.MustGenerate()