Random Integer Genreation
// GenerateRandomInt returns a random integer within the specified range [min, max)
func GenerateRandomInt(min int, max int) (int, error) {
if min >= max {
return 0, fmt.Errorf("invalid range: min %d >= max %d", min, max)
}
seed := time.Now().UnixNano()
randomizer := rand.New(rand.NewSource(seed))
return randomizer.Intn(max-min) + min, nil
}
Generating Unique Random Sequences
// GenerateUniqueRandomSequence creates a slice of unique random integers in range [min, max)
func GenerateUniqueRandomSequence(min, max, size int) ([]int, error) {
if min >= max {
return nil, fmt.Errorf("invalid range [%d, %d)", min, max)
}
if size > max-min {
return nil, fmt.Errorf("requested size %d exceeds available numbers %d", size, max-min)
}
// Create sequential slice of all possible numbers
availableNumbers := make([]int, max-min)
for i := range availableNumbers {
availableNumbers[i] = min + i
}
// Shuffle using cryptographic random seed
cryptoSeed, _ := rand.Int(rand.Reader, big.NewInt(1<<63-1))
shuffler := rand.New(rand.NewSource(cryptoSeed.Int64()))
shuffler.Shuffle(len(availableNumbers), func(i, j int) {
availableNumbers[i], availableNumbers[j] = availableNumbers[j], availableNumbers[i]
})
return availableNumbers[:size], nil
}
Optimized Algorithm for Large Ranges
func GenerateUniqueRandomNumbers(min, max, count int) ([]int, error) {
if min >= max {
return nil, fmt.Errorf("invalid range [%d, %d)", min, max)
}
if count > max-min {
return nil, fmt.Errorf("count %d exceeds range size %d", count, max-min)
}
totalNumbers := max - min
// For small ranges or when selecting most numbers, use shuffle approach
if totalNumbers <= 1000 || count > totalNumbers/2 {
sequence := make([]int, totalNumbers)
for i := 0; i < totalNumbers; i++ {
sequence[i] = min + i
}
cryptoSeed, _ := rand.Int(rand.Reader, big.NewInt(1<<63-1))
rng := rand.New(rand.NewSource(cryptoSeed.Int64()))
rng.Shuffle(len(sequence), func(i, j int) {
sequence[i], sequence[j] = sequence[j], sequence[i]
})
return sequence[:count], nil
}
// For large ranges, use reservoir sampling
result := make([]int, count)
for i := 0; i < count; i++ {
result[i] = min + i
}
cryptoSeed, _ := rand.Int(rand.Reader, big.NewInt(1<<63-1))
rng := rand.New(rand.NewSource(cryptoSeed.Int64()))
for i := count; i < totalNumbers; i++ {
randomIndex := rng.Intn(i + 1)
if randomIndex < count {
result[randomIndex] = min + i
}
}
return result, nil
}
Both functions utilize time-based seeding suitable for general use cases. For enhanced security requirements, cryptographic random number generation provides stronger ranodmness guarantees.