Provides functionality to generate unique random numbers within a specified range.
- Generate unique random numbers within a specified range.
- Configure the range and the source of random numbers.
- Optimized for short ranges.
- Verify if a number is currently consumed from the specified range.
- Offers a way to reuse (re-generate) a previously generated number.
- Get the number of unique random numbers used from the range so far.
- Modular and easy-to-use API.
Note: Check out v2 for more custom config and Generics support.
go1.18or higher.
go get github.com/asmsh/uniquerand
package main
import (
"fmt"
"github.com/asmsh/uniquerand"
)
func main() {
uri := uniquerand.Int{}
uri.Reset(20)
for i, ok := uri.Get(); ok; i, ok = uri.Get() {
// do something with 'i'...
fmt.Println("i", i)
// if you are interested in getting the same 'i' value later,
// return it to the rand source, and it will be randomly returned
// via a future call to Get.
// uri.Put(i)
}
// print some statistics
fmt.Println("Num generated:", uri.Count(), "out of", uri.Range())
}go: go1.25.5
goos: darwin
goarch: arm64
pkg: github.com/asmsh/uniquerand
cpu: Apple M2
Benchmark_Int/Get
Benchmark_Int/Get/default-8 167364 65.98 ns/op 0 B/op 0 allocs/op
Benchmark_Int/Get/range_32-8 190920 64.84 ns/op 0 B/op 0 allocs/op
Benchmark_Int/Get/range_64-8 177037 71.24 ns/op 0 B/op 0 allocs/op
Benchmark_Int/Get/range_256-8 168148 72.68 ns/op 0 B/op 0 allocs/op
Benchmark_Int/Get/range_1024-8 165560 71.00 ns/op 0 B/op 0 allocs/op
Benchmark_Int/Get/range_4096-8 167769 71.13 ns/op 0 B/op 0 allocs/op
Benchmark_Int/Put
Benchmark_Int/Put/default-8 167050 71.66 ns/op 0 B/op 0 allocs/op
Benchmark_Int/Put/range_32-8 164490 73.28 ns/op 0 B/op 0 allocs/op
Benchmark_Int/Put/range_64-8 154273 73.99 ns/op 0 B/op 0 allocs/op
Benchmark_Int/Put/range_256-8 147817 81.53 ns/op 0 B/op 0 allocs/op
Benchmark_Int/Put/range_1024-8 145326 79.00 ns/op 0 B/op 0 allocs/op
Benchmark_Int/Put/range_4096-8 145598 80.88 ns/op 0 B/op 0 allocs/op
Benchmark_Int/Get_&_Put
Benchmark_Int/Get_&_Put/default-8 1073421 10.86 ns/op 0 B/op 0 allocs/op
Benchmark_Int/Get_&_Put/range_32-8 946431 10.83 ns/op 0 B/op 0 allocs/op
Benchmark_Int/Get_&_Put/range_64-8 741885 15.92 ns/op 0 B/op 0 allocs/op
Benchmark_Int/Get_&_Put/range_256-8 861758 12.65 ns/op 0 B/op 0 allocs/op
Benchmark_Int/Get_&_Put/range_1024-8 1000000 12.54 ns/op 0 B/op 0 allocs/op
Benchmark_Int/Get_&_Put/range_4096-8 1000000 11.82 ns/op 0 B/op 0 allocs/op
Benchmark_Int/Rest_&_Get
Benchmark_Int/Rest_&_Get/default-8 889417 12.05 ns/op 0 B/op 0 allocs/op
Benchmark_Int/Rest_&_Get/range_32-8 1000000 10.79 ns/op 0 B/op 0 allocs/op
Benchmark_Int/Rest_&_Get/range_64-8 454544 23.89 ns/op 4 B/op 1 allocs/op
Benchmark_Int/Rest_&_Get/range_256-8 523730 24.58 ns/op 32 B/op 1 allocs/op
Benchmark_Int/Rest_&_Get/range_1024-8 336408 30.79 ns/op 128 B/op 1 allocs/op
Benchmark_Int/Rest_&_Get/range_4096-8 196464 70.93 ns/op 512 B/op 1 allocs/op
It depends on another Random Number Generator (RNG) (the randomness source) for generating numbers at first.
It checks for the uniqueness of the generated number against a bits-memory.
If the generated number (by the RNG) is found to be not unique, it replaces it with the nearest unique number not used within the specified range.
Limitation: The algorithm for returning the nearest unique number (replacing algo) is not random, however, it could cause the Get method to produce sequential numbers only in the case of the RNG returning the same number over and over.