Files
bl/common/utils/random/random.go

144 lines
3.4 KiB
Go
Raw Normal View History

package random
import (
"math/rand"
"time"
)
// RandomXS128 实现 xorshift128+ 伪随机数生成器
type RandomXS128 struct {
seed0 uint64 // 内部状态前半部分
seed1 uint64 // 内部状态后半部分
}
// 归一化常数
const (
normDouble = 1.0 / (1 << 53)
normFloat = 1.0 / (1 << 24)
)
// NewRandomXS128 创建一个新的随机数生成器,自动生成初始种子
func NewRandomXS128() *RandomXS128 {
// 用系统随机数初始化种子(模拟 Java 中 new Random().nextLong() 的行为)
// 实际使用中可替换为更安全的种子源(如 crypto/rand
source := rand.NewSource(time.Now().UnixNano()) // 基于时间的种子源
r := rand.New(source) // 用种子源创建 Rand 实例
seed := uint64(r.Int())<<32 | uint64(r.Int())
return NewRandomXS128WithSeed(seed)
}
// NewRandomXS128WithSeed 用单个 uint64 种子创建生成器
func NewRandomXS128WithSeed(seed uint64) *RandomXS128 {
seed0 := murmurHash3(seed)
seed1 := murmurHash3(seed0)
return &RandomXS128{seed0: seed0, seed1: seed1}
}
// NewRandomXS128WithTwoSeeds 用两个 uint64 种子直接设置状态
func NewRandomXS128WithTwoSeeds(seed0, seed1 uint64) *RandomXS128 {
return &RandomXS128{seed0: seed0, seed1: seed1}
}
// NextLong 生成下一个 64 位随机整数
func (r *RandomXS128) NextLong() uint64 {
s1 := r.seed0
s0 := r.seed1
r.seed0 = s0
s1 ^= s1 << 23
r.seed1 = s1 ^ s0 ^ (s1 >> 17) ^ (s0 >> 26)
return r.seed1 + s0
}
// NextInt 生成下一个 32 位随机整数
func (r *RandomXS128) NextInt() int {
return int(r.NextLong() & 0xFFFFFFFF)
}
// NextIntN 生成 [0, n) 范围内的随机整数
func (r *RandomXS128) NextIntN(n int) int {
if n <= 0 {
panic("n must be positive")
}
for {
bits := int(r.NextLong() >> 1)
value := int(bits % n)
if bits-value+n-1 >= 0 {
return value
}
}
}
// NextLongN 生成 [0, n) 范围内的随机 64 位整数
func (r *RandomXS128) NextLongN(n uint64) uint64 {
if n <= 0 {
panic("n must be positive")
}
for {
bits := r.NextLong() >> 1
value := bits % n
if bits-value+(n-1) >= 0 {
return value
}
}
}
// NextDouble 生成 [0.0, 1.0) 范围内的随机浮点数
func (r *RandomXS128) NextDouble() float64 {
return float64(r.NextLong()>>11) * normDouble
}
// NextFloat 生成 [0.0, 1.0) 范围内的随机单精度浮点数
func (r *RandomXS128) NextFloat() float32 {
return float32(float64(r.NextLong()>>40) * normFloat)
}
// NextBoolean 生成随机布尔值
func (r *RandomXS128) NextBoolean() bool {
return (r.NextLong() & 1) != 0
}
// NextBytes 填充字节数组为随机字节
func (r *RandomXS128) NextBytes(b []byte) {
i := len(b)
for i > 0 {
n := i
if n > 8 {
n = 8
}
bits := r.NextLong()
for j := 0; j < n; j++ {
b[i-1-j] = byte(bits >> (8 * j))
}
i -= n
}
}
// SetSeed 用单个种子重置生成器状态
func (r *RandomXS128) SetSeed(seed uint64) {
seed0 := murmurHash3(seed)
r.seed0 = seed0
r.seed1 = murmurHash3(seed0)
}
// SetState 直接设置内部状态
func (r *RandomXS128) SetState(seed0, seed1 uint64) {
r.seed0 = seed0
r.seed1 = seed1
}
// GetState 获取内部状态
func (r *RandomXS128) GetState() (seed0, seed1 uint64) {
return r.seed0, r.seed1
}
// murmurHash3 用于种子扩展的哈希函数
func murmurHash3(x uint64) uint64 {
x ^= x >> 33
x *= 0xff51afd7ed558ccd
x ^= x >> 33
x *= 0xc4ceb9fe1a85ec53
x ^= x >> 33
return x
}