A simple, fast, and efficient Go implementation of Nano ID, a tiny, secure, URL-friendly, unique string ID generator.
Please see the godoc for detailed documentation.
- Short & Unique IDs: Generates compact and collision-resistant identifiers.
- Cryptographically Secure: Utilizes Go's
crypto/rand
andx/crypto/chacha20
stream cypher package for generating cryptographically secure random numbers. This guarantees that the generated IDs are both unpredictable and suitable for security-sensitive applications. - Customizable:
- Define your own set of characters for ID generation with a minimum length of 2 characters and maximum length of 256 characters.
- Define your own random number generator.
- Unicode and ASCII alphabets supported.
- Concurrency Safe: Designed to be safe for use in concurrent environments.
- High Performance: Optimized with buffer pooling to minimize allocations and enhance speed.
- Optimized for Low Allocations: Carefully structured to minimize heap allocations, reducing memory overhead and improving cache locality. This optimization is crucial for applications where performance and resource usage are critical.
- 1
allocs/op
for ASCII and Unicode alphabets regardless of alphabet size or generated ID length.
- 1
- Zero Dependencies: Lightweight implementation with no external dependencies beyond the standard library.
- Supports
io.Reader
Interface:- The Nano ID generator satisfies the
io.Reader
interface, allowing it to be used interchangeably with anyio.Reader
implementations. - Developers can utilize the Nano ID generator in contexts such as streaming data processing, pipelines, and other I/O-driven operations.
- The Nano ID generator satisfies the
Please see the Nano ID CLI for a command-line interface (CLI) that uses this package to generate Nano IDs.
To install the Nano ID package, run the following command:
go get -u github.com/sixafter/nanoid
To use the NanoID package in your Go project, import it as follows:
import "github.com/sixafter/nanoid"
The simplest way to generate a Nano ID is by using the default settings. This utilizes the predefined alphabet and default ID length.
package main
import (
"fmt"
"github.com/sixafter/nanoid"
)
func main() {
id, err := nanoid.New()
if err != nil {
panic(err)
}
fmt.Println("Generated ID:", id)
}
Output:
Generated ID: mGbzQkkPBidjL4IP_MwBM
Generate a NanoID with a custom length.
package main
import (
"fmt"
"github.com/sixafter/nanoid"
)
func main() {
id, err := nanoid.NewWithLength(10)
if err != nil {
panic(err)
}
fmt.Println("Generated ID:", id)
}
Output:
Generated ID: 1A3F5B7C9D
Here's a simple example demonstrating how to use the Nano ID generator as an io.Reader
:
package main
import (
"fmt"
"io"
"github.com/sixafter/nanoid"
)
func main() {
// Nano ID default length is 21
buf := make([]byte, nanoid.DefaultLength)
// Read a Nano ID into the buffer
_, err := nanoid.Read(buf)
if err != nil && err != io.EOF {
panic(err)
}
// Convert the byte slice to a string
id := string(buf)
fmt.Printf("Generated ID: %s\n", id)
}
Output:
Generated ID: 2mhTvy21bBZhZcd80ZydM
You can customize the alphabet by using the WithAlphabet option and generate an ID with a custom length.
package main
import (
"fmt"
"github.com/sixafter/nanoid"
)
func main() {
// Define a custom alphabet
alphabet := "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
// Create a new generator with custom alphabet and length hint
gen, err := nanoid.NewGenerator(
nanoid.WithAlphabet(alphabet),
nanoid.WithLengthHint(10),
)
if err != nil {
fmt.Println("Error creating Nano ID generator:", err)
return
}
// Generate a Nano ID using the custom generator
id, err := gen.New(10)
if err != nil {
fmt.Println("Error generating Nano ID:", err)
return
}
fmt.Println("Generated ID:", id)
}
Output"
Generated ID: G5J8K2M0QZ
You can customize the random number generator by using the WithRandReader option and generate an ID.
package main
import (
"crypto/rand"
"fmt"
"github.com/sixafter/nanoid"
)
func main() {
// Create a new generator with custom random number generator
gen, err := nanoid.NewGenerator(
nanoid.WithRandReader(rand.Reader),
)
if err != nil {
fmt.Println("Error creating Nano ID generator:", err)
return
}
// Generate a Nano ID using the custom generator
id, err := gen.New(nanoid.DefaultLength)
if err != nil {
fmt.Println("Error generating Nano ID:", err)
return
}
fmt.Println("Generated ID:", id)
}
Output"
Generated ID: A8I8K3J0QY
The nanoid generator utilizes sync.Pool
to manage byte slice buffers efficiently. This approach minimizes memory allocations and enhances performance, especially in high-concurrency scenarios.
How It Works:
- Storing Pointers:
sync.Pool
stores pointers to[]byte
(or[]rune
if Unicode) slices (*[]byte
) instead of the slices themselves. This avoids unnecessary allocations and aligns with best practices for usingsync.Pool
. - Zeroing Buffers: Before returning buffers to the pool, they are zeroed out to prevent data leaks.
The generator
struct is optimized for memory alignment and size by ordering from largest to smallest to minimize padding and optimize memory usage.
Run the benchmarks using the go test
command with the bench
make target:
make bench
Sample output might look like this:
Expand to see results
go test -bench=. -benchmem -memprofile=mem.out -cpuprofile=cpu.out
goos: darwin
goarch: arm64
pkg: github.com/sixafter/nanoid
cpu: Apple M4 Max
BenchmarkNanoIDAllocations-16 15003954 76.30 ns/op 24 B/op 1 allocs/op
BenchmarkNanoIDAllocationsConcurrent-16 74179202 15.76 ns/op 24 B/op 1 allocs/op
BenchmarkGenerator_Read_DefaultLength-16 16803123 68.10 ns/op 24 B/op 1 allocs/op
BenchmarkGenerator_Read_VaryingBufferSizes/BufferSize_2-16 33585614 36.13 ns/op 2 B/op 1 allocs/op
BenchmarkGenerator_Read_VaryingBufferSizes/BufferSize_3-16 31765290 38.20 ns/op 3 B/op 1 allocs/op
BenchmarkGenerator_Read_VaryingBufferSizes/BufferSize_5-16 28791708 42.14 ns/op 5 B/op 1 allocs/op
BenchmarkGenerator_Read_VaryingBufferSizes/BufferSize_13-16 22228155 55.78 ns/op 16 B/op 1 allocs/op
BenchmarkGenerator_Read_VaryingBufferSizes/BufferSize_21-16 18243597 65.63 ns/op 24 B/op 1 allocs/op
BenchmarkGenerator_Read_VaryingBufferSizes/BufferSize_34-16 13976239 86.27 ns/op 48 B/op 1 allocs/op
BenchmarkGenerator_Read_ZeroLengthBuffer-16 816275398 1.372 ns/op 0 B/op 0 allocs/op
BenchmarkGenerator_Read_Concurrent/Concurrency_1-16 17746567 66.30 ns/op 24 B/op 1 allocs/op
BenchmarkGenerator_Read_Concurrent/Concurrency_2-16 33351552 36.08 ns/op 24 B/op 1 allocs/op
BenchmarkGenerator_Read_Concurrent/Concurrency_4-16 55830726 21.93 ns/op 24 B/op 1 allocs/op
BenchmarkGenerator_Read_Concurrent/Concurrency_8-16 60704806 18.97 ns/op 24 B/op 1 allocs/op
BenchmarkGenerator_Read_Concurrent/Concurrency_16-16 67446042 16.91 ns/op 24 B/op 1 allocs/op
BenchmarkNanoIDGeneration/ASCII_AlphabetLen2/IDLen8-16 25284205 46.18 ns/op 8 B/op 1 allocs/op
BenchmarkNanoIDGeneration/ASCII_AlphabetLen2/IDLen16-16 20124421 58.75 ns/op 16 B/op 1 allocs/op
BenchmarkNanoIDGeneration/ASCII_AlphabetLen2/IDLen21-16 18030165 65.83 ns/op 24 B/op 1 allocs/op
BenchmarkNanoIDGeneration/ASCII_AlphabetLen2/IDLen32-16 14527756 82.23 ns/op 32 B/op 1 allocs/op
BenchmarkNanoIDGeneration/ASCII_AlphabetLen2/IDLen64-16 8959059 134.7 ns/op 64 B/op 1 allocs/op
BenchmarkNanoIDGeneration/ASCII_AlphabetLen2/IDLen128-16 5327983 225.5 ns/op 128 B/op 1 allocs/op
BenchmarkNanoIDGeneration/ASCII_AlphabetLen16/IDLen8-16 24694173 45.10 ns/op 8 B/op 1 allocs/op
BenchmarkNanoIDGeneration/ASCII_AlphabetLen16/IDLen16-16 20262411 57.76 ns/op 16 B/op 1 allocs/op
BenchmarkNanoIDGeneration/ASCII_AlphabetLen16/IDLen21-16 18349347 65.79 ns/op 24 B/op 1 allocs/op
BenchmarkNanoIDGeneration/ASCII_AlphabetLen16/IDLen32-16 14576307 81.71 ns/op 32 B/op 1 allocs/op
BenchmarkNanoIDGeneration/ASCII_AlphabetLen16/IDLen64-16 8961514 133.6 ns/op 64 B/op 1 allocs/op
BenchmarkNanoIDGeneration/ASCII_AlphabetLen16/IDLen128-16 5336977 224.3 ns/op 128 B/op 1 allocs/op
BenchmarkNanoIDGeneration/ASCII_AlphabetLen32/IDLen8-16 26897259 46.21 ns/op 8 B/op 1 allocs/op
BenchmarkNanoIDGeneration/ASCII_AlphabetLen32/IDLen16-16 20310639 58.69 ns/op 16 B/op 1 allocs/op
BenchmarkNanoIDGeneration/ASCII_AlphabetLen32/IDLen21-16 17752453 67.27 ns/op 24 B/op 1 allocs/op
BenchmarkNanoIDGeneration/ASCII_AlphabetLen32/IDLen32-16 14871600 80.86 ns/op 32 B/op 1 allocs/op
BenchmarkNanoIDGeneration/ASCII_AlphabetLen32/IDLen64-16 9064250 134.2 ns/op 64 B/op 1 allocs/op
BenchmarkNanoIDGeneration/ASCII_AlphabetLen32/IDLen128-16 5340874 223.6 ns/op 128 B/op 1 allocs/op
BenchmarkNanoIDGeneration/ASCII_AlphabetLen64/IDLen8-16 26052786 45.81 ns/op 8 B/op 1 allocs/op
BenchmarkNanoIDGeneration/ASCII_AlphabetLen64/IDLen16-16 20089396 57.76 ns/op 16 B/op 1 allocs/op
BenchmarkNanoIDGeneration/ASCII_AlphabetLen64/IDLen21-16 18227050 65.65 ns/op 24 B/op 1 allocs/op
BenchmarkNanoIDGeneration/ASCII_AlphabetLen64/IDLen32-16 14711966 81.99 ns/op 32 B/op 1 allocs/op
BenchmarkNanoIDGeneration/ASCII_AlphabetLen64/IDLen64-16 8971347 134.5 ns/op 64 B/op 1 allocs/op
BenchmarkNanoIDGeneration/ASCII_AlphabetLen64/IDLen128-16 5296887 226.6 ns/op 128 B/op 1 allocs/op
BenchmarkNanoIDGeneration/Unicode_AlphabetLen2/IDLen8-16 16784506 70.18 ns/op 24 B/op 1 allocs/op
BenchmarkNanoIDGeneration/Unicode_AlphabetLen2/IDLen16-16 11497441 104.4 ns/op 48 B/op 1 allocs/op
BenchmarkNanoIDGeneration/Unicode_AlphabetLen2/IDLen21-16 9549919 125.2 ns/op 48 B/op 1 allocs/op
BenchmarkNanoIDGeneration/Unicode_AlphabetLen2/IDLen32-16 6733585 178.0 ns/op 80 B/op 1 allocs/op
BenchmarkNanoIDGeneration/Unicode_AlphabetLen2/IDLen64-16 3697659 326.2 ns/op 144 B/op 1 allocs/op
BenchmarkNanoIDGeneration/Unicode_AlphabetLen2/IDLen128-16 1986321 607.8 ns/op 289 B/op 1 allocs/op
BenchmarkNanoIDGeneration/Unicode_AlphabetLen16/IDLen8-16 17139867 69.70 ns/op 24 B/op 1 allocs/op
BenchmarkNanoIDGeneration/Unicode_AlphabetLen16/IDLen16-16 11514620 104.0 ns/op 48 B/op 1 allocs/op
BenchmarkNanoIDGeneration/Unicode_AlphabetLen16/IDLen21-16 9670254 123.7 ns/op 48 B/op 1 allocs/op
BenchmarkNanoIDGeneration/Unicode_AlphabetLen16/IDLen32-16 6933122 173.9 ns/op 80 B/op 1 allocs/op
BenchmarkNanoIDGeneration/Unicode_AlphabetLen16/IDLen64-16 3671619 324.5 ns/op 144 B/op 1 allocs/op
BenchmarkNanoIDGeneration/Unicode_AlphabetLen16/IDLen128-16 1984659 601.5 ns/op 289 B/op 1 allocs/op
BenchmarkNanoIDGeneration/Unicode_AlphabetLen32/IDLen8-16 17377945 68.67 ns/op 24 B/op 1 allocs/op
BenchmarkNanoIDGeneration/Unicode_AlphabetLen32/IDLen16-16 11687414 103.8 ns/op 48 B/op 1 allocs/op
BenchmarkNanoIDGeneration/Unicode_AlphabetLen32/IDLen21-16 9423592 126.0 ns/op 48 B/op 1 allocs/op
BenchmarkNanoIDGeneration/Unicode_AlphabetLen32/IDLen32-16 6661424 179.6 ns/op 80 B/op 1 allocs/op
BenchmarkNanoIDGeneration/Unicode_AlphabetLen32/IDLen64-16 3693400 322.7 ns/op 144 B/op 1 allocs/op
BenchmarkNanoIDGeneration/Unicode_AlphabetLen32/IDLen128-16 1993962 604.1 ns/op 289 B/op 1 allocs/op
BenchmarkNanoIDGeneration/Unicode_AlphabetLen64/IDLen8-16 17084515 69.71 ns/op 24 B/op 1 allocs/op
BenchmarkNanoIDGeneration/Unicode_AlphabetLen64/IDLen16-16 11476266 103.1 ns/op 48 B/op 1 allocs/op
BenchmarkNanoIDGeneration/Unicode_AlphabetLen64/IDLen21-16 9785174 125.6 ns/op 48 B/op 1 allocs/op
BenchmarkNanoIDGeneration/Unicode_AlphabetLen64/IDLen32-16 6641458 178.9 ns/op 80 B/op 1 allocs/op
BenchmarkNanoIDGeneration/Unicode_AlphabetLen64/IDLen64-16 3680024 325.8 ns/op 144 B/op 1 allocs/op
BenchmarkNanoIDGeneration/Unicode_AlphabetLen64/IDLen128-16 1970880 608.1 ns/op 289 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/ASCII_AlphabetLen2/IDLen8-16 155731814 7.966 ns/op 8 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/ASCII_AlphabetLen2/IDLen16-16 100000000 10.72 ns/op 16 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/ASCII_AlphabetLen2/IDLen21-16 88434433 12.91 ns/op 24 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/ASCII_AlphabetLen2/IDLen32-16 76901302 15.83 ns/op 32 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/ASCII_AlphabetLen2/IDLen64-16 44088199 26.29 ns/op 64 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/ASCII_AlphabetLen2/IDLen128-16 25929686 45.83 ns/op 128 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/ASCII_AlphabetLen16/IDLen8-16 159970467 7.688 ns/op 8 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/ASCII_AlphabetLen16/IDLen16-16 100000000 10.46 ns/op 16 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/ASCII_AlphabetLen16/IDLen21-16 91863391 12.60 ns/op 24 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/ASCII_AlphabetLen16/IDLen32-16 71162065 15.79 ns/op 32 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/ASCII_AlphabetLen16/IDLen64-16 44062299 26.30 ns/op 64 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/ASCII_AlphabetLen16/IDLen128-16 26455730 44.79 ns/op 128 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/ASCII_AlphabetLen32/IDLen8-16 162121165 7.687 ns/op 8 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/ASCII_AlphabetLen32/IDLen16-16 100000000 10.86 ns/op 16 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/ASCII_AlphabetLen32/IDLen21-16 83806197 13.03 ns/op 24 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/ASCII_AlphabetLen32/IDLen32-16 75761760 15.57 ns/op 32 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/ASCII_AlphabetLen32/IDLen64-16 45690134 25.44 ns/op 64 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/ASCII_AlphabetLen32/IDLen128-16 26845486 44.60 ns/op 128 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/ASCII_AlphabetLen64/IDLen8-16 160724536 7.605 ns/op 8 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/ASCII_AlphabetLen64/IDLen16-16 100000000 10.66 ns/op 16 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/ASCII_AlphabetLen64/IDLen21-16 91057120 12.44 ns/op 24 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/ASCII_AlphabetLen64/IDLen32-16 75076638 15.30 ns/op 32 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/ASCII_AlphabetLen64/IDLen64-16 45273408 26.00 ns/op 64 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/ASCII_AlphabetLen64/IDLen128-16 26638818 44.49 ns/op 128 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/Unicode_AlphabetLen2/IDLen8-16 86501292 12.93 ns/op 24 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/Unicode_AlphabetLen2/IDLen16-16 54813188 20.64 ns/op 48 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/Unicode_AlphabetLen2/IDLen21-16 53420488 22.20 ns/op 48 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/Unicode_AlphabetLen2/IDLen32-16 36231016 31.31 ns/op 80 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/Unicode_AlphabetLen2/IDLen64-16 22430011 53.27 ns/op 144 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/Unicode_AlphabetLen2/IDLen128-16 12645932 96.45 ns/op 288 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/Unicode_AlphabetLen16/IDLen8-16 93198150 12.98 ns/op 24 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/Unicode_AlphabetLen16/IDLen16-16 58279538 19.86 ns/op 48 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/Unicode_AlphabetLen16/IDLen21-16 55201494 21.39 ns/op 48 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/Unicode_AlphabetLen16/IDLen32-16 37473552 31.02 ns/op 80 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/Unicode_AlphabetLen16/IDLen64-16 22530309 53.32 ns/op 144 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/Unicode_AlphabetLen16/IDLen128-16 12306376 96.18 ns/op 288 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/Unicode_AlphabetLen32/IDLen8-16 88192876 12.87 ns/op 24 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/Unicode_AlphabetLen32/IDLen16-16 57457620 20.01 ns/op 48 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/Unicode_AlphabetLen32/IDLen21-16 53846470 21.74 ns/op 48 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/Unicode_AlphabetLen32/IDLen32-16 37763508 31.43 ns/op 80 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/Unicode_AlphabetLen32/IDLen64-16 22099260 54.05 ns/op 144 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/Unicode_AlphabetLen32/IDLen128-16 12431437 96.13 ns/op 288 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/Unicode_AlphabetLen64/IDLen8-16 84577526 12.84 ns/op 24 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/Unicode_AlphabetLen64/IDLen16-16 58122990 19.93 ns/op 48 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/Unicode_AlphabetLen64/IDLen21-16 52644855 21.77 ns/op 48 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/Unicode_AlphabetLen64/IDLen32-16 37568679 31.45 ns/op 80 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/Unicode_AlphabetLen64/IDLen64-16 22077678 54.60 ns/op 144 B/op 1 allocs/op
BenchmarkNanoIDGenerationParallel/Unicode_AlphabetLen64/IDLen128-16 12427960 96.53 ns/op 288 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/ASCII_AlphabetLen2/IDLen8-16 24682723 45.65 ns/op 8 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/ASCII_AlphabetLen2/IDLen16-16 19997860 59.69 ns/op 16 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/ASCII_AlphabetLen2/IDLen21-16 17316693 69.90 ns/op 24 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/ASCII_AlphabetLen2/IDLen32-16 13858519 86.02 ns/op 32 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/ASCII_AlphabetLen2/IDLen64-16 8383051 144.3 ns/op 64 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/ASCII_AlphabetLen2/IDLen128-16 4923039 243.1 ns/op 128 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/ASCII_AlphabetLen16/IDLen8-16 25041670 46.75 ns/op 8 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/ASCII_AlphabetLen16/IDLen16-16 19813886 60.98 ns/op 16 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/ASCII_AlphabetLen16/IDLen21-16 17404220 69.12 ns/op 24 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/ASCII_AlphabetLen16/IDLen32-16 13892030 85.15 ns/op 32 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/ASCII_AlphabetLen16/IDLen64-16 8509674 141.9 ns/op 64 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/ASCII_AlphabetLen16/IDLen128-16 4921491 241.0 ns/op 128 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/ASCII_AlphabetLen32/IDLen8-16 25172382 47.19 ns/op 8 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/ASCII_AlphabetLen32/IDLen16-16 19663951 60.46 ns/op 16 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/ASCII_AlphabetLen32/IDLen21-16 17468212 68.51 ns/op 24 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/ASCII_AlphabetLen32/IDLen32-16 14062369 85.35 ns/op 32 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/ASCII_AlphabetLen32/IDLen64-16 8480640 141.5 ns/op 64 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/ASCII_AlphabetLen32/IDLen128-16 5044694 238.8 ns/op 128 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/ASCII_AlphabetLen64/IDLen8-16 26560914 45.30 ns/op 8 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/ASCII_AlphabetLen64/IDLen16-16 19941325 60.39 ns/op 16 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/ASCII_AlphabetLen64/IDLen21-16 17160159 68.94 ns/op 24 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/ASCII_AlphabetLen64/IDLen32-16 13838980 86.89 ns/op 32 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/ASCII_AlphabetLen64/IDLen64-16 8455816 140.1 ns/op 64 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/ASCII_AlphabetLen64/IDLen128-16 5122021 234.6 ns/op 128 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/Unicode_AlphabetLen2/IDLen8-16 16634562 71.56 ns/op 24 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/Unicode_AlphabetLen2/IDLen16-16 11221044 107.0 ns/op 48 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/Unicode_AlphabetLen2/IDLen21-16 9227674 129.0 ns/op 48 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/Unicode_AlphabetLen2/IDLen32-16 6767592 178.3 ns/op 80 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/Unicode_AlphabetLen2/IDLen64-16 3574780 333.7 ns/op 144 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/Unicode_AlphabetLen2/IDLen128-16 1922041 628.0 ns/op 288 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/Unicode_AlphabetLen16/IDLen8-16 16603988 70.65 ns/op 24 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/Unicode_AlphabetLen16/IDLen16-16 11450854 106.3 ns/op 48 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/Unicode_AlphabetLen16/IDLen21-16 9321528 128.2 ns/op 48 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/Unicode_AlphabetLen16/IDLen32-16 6649005 182.6 ns/op 80 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/Unicode_AlphabetLen16/IDLen64-16 3578170 333.0 ns/op 144 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/Unicode_AlphabetLen16/IDLen128-16 1946996 617.6 ns/op 288 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/Unicode_AlphabetLen32/IDLen8-16 16661652 71.52 ns/op 24 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/Unicode_AlphabetLen32/IDLen16-16 11298946 106.5 ns/op 48 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/Unicode_AlphabetLen32/IDLen21-16 9353600 128.5 ns/op 48 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/Unicode_AlphabetLen32/IDLen32-16 6632572 179.0 ns/op 80 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/Unicode_AlphabetLen32/IDLen64-16 3584874 333.7 ns/op 144 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/Unicode_AlphabetLen32/IDLen128-16 1914860 624.4 ns/op 288 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/Unicode_AlphabetLen64/IDLen8-16 16383211 70.89 ns/op 24 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/Unicode_AlphabetLen64/IDLen16-16 11173053 107.2 ns/op 48 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/Unicode_AlphabetLen64/IDLen21-16 9277276 128.6 ns/op 48 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/Unicode_AlphabetLen64/IDLen32-16 6546392 182.6 ns/op 80 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/Unicode_AlphabetLen64/IDLen64-16 3611689 334.5 ns/op 144 B/op 1 allocs/op
BenchmarkNanoIDWithVaryingAlphabetLengths/Unicode_AlphabetLen64/IDLen128-16 1939897 618.9 ns/op 288 B/op 1 allocs/op
PASS
ok github.com/sixafter/nanoid 210.925s
ns/op
: Nanoseconds per operation. Lower values indicate faster performance.B/op
: Bytes allocated per operation. Lower values indicate more memory-efficient code.allocs/op
: Number of memory allocations per operation. Fewer allocations generally lead to better performance.
Nano ID generates unique identifiers based on the following:
- Random Byte Generation: Nano ID generates a sequence of random bytes using a secure random source (e.g.,
crypto/rand.Reader
). - Mapping to Alphabet: Each random byte is mapped to a character in a predefined alphabet to form the final ID.
- Uniform Distribution: To ensure that each character in the alphabet has an equal probability of being selected, Nano ID employs techniques to avoid bias, especially when the alphabet size isn't a power of two.
- Alphabet Lengths:
- At Least Two Characters: The custom alphabet must contain at least two unique characters. An alphabet with fewer than two characters cannot produce IDs with sufficient variability or randomness.
- Maximum Length 256 Characters: The implementation utilizes a rune-based approach, where each character in the alphabet is represented by a single rune. This allows for a broad range of unique characters, accommodating alphabets with up to 256 distinct runes. Attempting to use an alphabet with more than 256 runes will result in an error.
- Uniqueness of Characters:
- All Characters Must Be Unique. Duplicate characters in the alphabet can introduce biases in ID generation and compromise the randomness and uniqueness of the IDs. The generator enforces uniqueness by checking for duplicates during initialization. If duplicates are detected, it will return an
ErrDuplicateCharacters
error.
- All Characters Must Be Unique. Duplicate characters in the alphabet can introduce biases in ID generation and compromise the randomness and uniqueness of the IDs. The generator enforces uniqueness by checking for duplicates during initialization. If duplicates are detected, it will return an
- Character Encoding:
- Support for ASCII and Unicode: The generator accepts alphabets containing Unicode characters, allowing you to include a wide range of symbols, emojis, or characters from various languages.
To determine the practical length for a NanoID for your use cases, see the collision time calculator here.
Contributions are welcome. See CONTRIBUTING
This project is licensed under the Apache 2.0 License. See LICENSE file.