fox/xrand/rand.go

66 lines
1.3 KiB
Go
Raw Normal View History

2025-05-25 20:02:15 +08:00
package xrand
import (
2025-06-13 10:29:58 +08:00
randx "crypto/rand"
"math"
"math/big"
2025-05-25 20:02:15 +08:00
"math/rand"
)
2025-05-26 16:02:54 +08:00
var rd *rand.Rand
2025-05-25 20:02:15 +08:00
func init() {
2025-06-13 10:29:58 +08:00
rd = rand.New(rand.NewSource(randInt64()))
}
// 用系统熵构建更自然的随机数,比"math/rand"构建的线性同余自然随机数要慢
func randInt64() int64 {
n, _ := randx.Int(randx.Reader, big.NewInt(math.MaxInt64))
return n.Int64()
2025-05-25 20:02:15 +08:00
}
2025-06-08 17:59:35 +08:00
// 随机值
2025-06-13 10:29:58 +08:00
func Rand[T int | int32 | int64 | uint32 | uint64]() T {
return T(randInt64())
2025-05-25 20:02:15 +08:00
}
2025-06-08 17:59:35 +08:00
// 从[0,n)范围里随机值
2025-06-13 10:29:58 +08:00
func RandN[T int | int32 | int64 | uint | uint32 | uint64](n T) T {
2025-06-08 17:59:35 +08:00
if int64(n) < 1 {
return 0
}
2025-06-13 10:29:58 +08:00
return T(randInt64() % int64(n)) // [0,n) 的随机整数
2025-05-25 20:02:15 +08:00
}
2025-06-13 10:29:58 +08:00
// 从[min,max)范围里随机值
2025-06-08 17:59:35 +08:00
func RandRange[T int | int32 | int64 | uint32 | uint64](min, max T) T {
if int64(max) < 1 || int64(min) < 1 || max < min {
return 0
}
return RandN[T](max-min) + min
2025-05-25 20:02:15 +08:00
}
func Perm(n int) []int {
2025-05-26 16:02:54 +08:00
return rd.Perm(n)
2025-05-25 20:02:15 +08:00
}
func Read(p []byte) (n int, err error) {
2025-05-26 16:02:54 +08:00
return rd.Read(p)
2025-05-25 20:02:15 +08:00
}
func Shuffle[T any](slice []T) {
rand.Shuffle(len(slice), func(i, j int) {
slice[i], slice[j] = slice[j], slice[i]
})
}
2025-06-06 00:09:35 +08:00
const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
func RandomString(n int) string {
b := make([]byte, n)
for i := range b {
b[i] = letterBytes[rd.Intn(len(letterBytes))]
}
return string(b)
}