diff --git a/xrand/rand.go b/xrand/rand.go index 656b512..894ab20 100644 --- a/xrand/rand.go +++ b/xrand/rand.go @@ -1,60 +1,38 @@ package xrand import ( + randx "crypto/rand" + "math" + "math/big" "math/rand" - "time" ) var rd *rand.Rand func init() { - rd = rand.New(rand.NewSource(time.Now().UnixNano())) + rd = rand.New(rand.NewSource(randInt64())) +} + +// 用系统熵构建更自然的随机数,比"math/rand"构建的线性同余自然随机数要慢 +func randInt64() int64 { + n, _ := randx.Int(randx.Reader, big.NewInt(math.MaxInt64)) + return n.Int64() } // 随机值 -func Rand[T int | int32 | int64 | uint32 | uint64 | float32 | float64]() T { - switch any(T(0)).(type) { - case int: - return T(rd.Int()) - case int32: - return T(rd.Int31()) - case int64: - return T(rd.Int63()) - case uint32: - return T(rd.Uint32()) - case uint64: - return T(rd.Uint64()) - case float32: - return T(rd.Float32()) - case float64: - return T(rd.Float64()) - default: - panic("不支持的类型") - } +func Rand[T int | int32 | int64 | uint32 | uint64]() T { + return T(randInt64()) } // 从[0,n)范围里随机值 -func RandN[T int | int32 | int64 | uint32 | uint64](n T) T { +func RandN[T int | int32 | int64 | uint | uint32 | uint64](n T) T { if int64(n) < 1 { return 0 } - switch any(n).(type) { - case int: - return T(rd.Intn(int(n))) // [0,n) 的随机整数 - case int32: - return T(rd.Int31n(int32(n))) - case int64: - return T(rd.Int63n(int64(n))) - case uint32: - return T(rd.Uint32() % uint32(n)) // 注意:这里有小偏差 - case uint64: - return T(rand.Uint64() % uint64(n)) - default: - panic("不支持的类型") - } + return T(randInt64() % int64(n)) // [0,n) 的随机整数 } -// 从[0,n)范围里随机值 +// 从[min,max)范围里随机值 func RandRange[T int | int32 | int64 | uint32 | uint64](min, max T) T { if int64(max) < 1 || int64(min) < 1 || max < min { return 0