github.com/mdaxf/iac@v0.0.0-20240519030858-58a061660378/vendor_skip/go.mongodb.org/mongo-driver/internal/randutil/rand/rand.go (about) 1 // Copied from https://cs.opensource.google/go/x/exp/+/24438e51023af3bfc1db8aed43c1342817e8cfcd:rand/rand.go 2 3 // Copyright 2009 The Go Authors. All rights reserved. 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file. 6 7 // Package rand implements pseudo-random number generators. 8 // 9 // Random numbers are generated by a Source. Top-level functions, such as 10 // Float64 and Int, use a default shared Source that produces a deterministic 11 // sequence of values each time a program is run. Use the Seed function to 12 // initialize the default Source if different behavior is required for each run. 13 // The default Source, a LockedSource, is safe for concurrent use by multiple 14 // goroutines, but Sources created by NewSource are not. However, Sources are small 15 // and it is reasonable to have a separate Source for each goroutine, seeded 16 // differently, to avoid locking. 17 // 18 // For random numbers suitable for security-sensitive work, see the crypto/rand 19 // package. 20 package rand 21 22 import "sync" 23 24 // A Source represents a source of uniformly-distributed 25 // pseudo-random int64 values in the range [0, 1<<64). 26 type Source interface { 27 Uint64() uint64 28 Seed(seed uint64) 29 } 30 31 // NewSource returns a new pseudo-random Source seeded with the given value. 32 func NewSource(seed uint64) Source { 33 var rng PCGSource 34 rng.Seed(seed) 35 return &rng 36 } 37 38 // A Rand is a source of random numbers. 39 type Rand struct { 40 src Source 41 42 // readVal contains remainder of 64-bit integer used for bytes 43 // generation during most recent Read call. 44 // It is saved so next Read call can start where the previous 45 // one finished. 46 readVal uint64 47 // readPos indicates the number of low-order bytes of readVal 48 // that are still valid. 49 readPos int8 50 } 51 52 // New returns a new Rand that uses random values from src 53 // to generate other random values. 54 func New(src Source) *Rand { 55 return &Rand{src: src} 56 } 57 58 // Seed uses the provided seed value to initialize the generator to a deterministic state. 59 // Seed should not be called concurrently with any other Rand method. 60 func (r *Rand) Seed(seed uint64) { 61 if lk, ok := r.src.(*LockedSource); ok { 62 lk.seedPos(seed, &r.readPos) 63 return 64 } 65 66 r.src.Seed(seed) 67 r.readPos = 0 68 } 69 70 // Uint64 returns a pseudo-random 64-bit integer as a uint64. 71 func (r *Rand) Uint64() uint64 { return r.src.Uint64() } 72 73 // Int63 returns a non-negative pseudo-random 63-bit integer as an int64. 74 func (r *Rand) Int63() int64 { return int64(r.src.Uint64() &^ (1 << 63)) } 75 76 // Uint32 returns a pseudo-random 32-bit value as a uint32. 77 func (r *Rand) Uint32() uint32 { return uint32(r.Uint64() >> 32) } 78 79 // Int31 returns a non-negative pseudo-random 31-bit integer as an int32. 80 func (r *Rand) Int31() int32 { return int32(r.Uint64() >> 33) } 81 82 // Int returns a non-negative pseudo-random int. 83 func (r *Rand) Int() int { 84 u := uint(r.Uint64()) 85 return int(u << 1 >> 1) // clear sign bit. 86 } 87 88 const maxUint64 = (1 << 64) - 1 89 90 // Uint64n returns, as a uint64, a pseudo-random number in [0,n). 91 // It is guaranteed more uniform than taking a Source value mod n 92 // for any n that is not a power of 2. 93 func (r *Rand) Uint64n(n uint64) uint64 { 94 if n&(n-1) == 0 { // n is power of two, can mask 95 if n == 0 { 96 panic("invalid argument to Uint64n") 97 } 98 return r.Uint64() & (n - 1) 99 } 100 // If n does not divide v, to avoid bias we must not use 101 // a v that is within maxUint64%n of the top of the range. 102 v := r.Uint64() 103 if v > maxUint64-n { // Fast check. 104 ceiling := maxUint64 - maxUint64%n 105 for v >= ceiling { 106 v = r.Uint64() 107 } 108 } 109 110 return v % n 111 } 112 113 // Int63n returns, as an int64, a non-negative pseudo-random number in [0,n). 114 // It panics if n <= 0. 115 func (r *Rand) Int63n(n int64) int64 { 116 if n <= 0 { 117 panic("invalid argument to Int63n") 118 } 119 return int64(r.Uint64n(uint64(n))) 120 } 121 122 // Int31n returns, as an int32, a non-negative pseudo-random number in [0,n). 123 // It panics if n <= 0. 124 func (r *Rand) Int31n(n int32) int32 { 125 if n <= 0 { 126 panic("invalid argument to Int31n") 127 } 128 // TODO: Avoid some 64-bit ops to make it more efficient on 32-bit machines. 129 return int32(r.Uint64n(uint64(n))) 130 } 131 132 // Intn returns, as an int, a non-negative pseudo-random number in [0,n). 133 // It panics if n <= 0. 134 func (r *Rand) Intn(n int) int { 135 if n <= 0 { 136 panic("invalid argument to Intn") 137 } 138 // TODO: Avoid some 64-bit ops to make it more efficient on 32-bit machines. 139 return int(r.Uint64n(uint64(n))) 140 } 141 142 // Float64 returns, as a float64, a pseudo-random number in [0.0,1.0). 143 func (r *Rand) Float64() float64 { 144 // There is one bug in the value stream: r.Int63() may be so close 145 // to 1<<63 that the division rounds up to 1.0, and we've guaranteed 146 // that the result is always less than 1.0. 147 // 148 // We tried to fix this by mapping 1.0 back to 0.0, but since float64 149 // values near 0 are much denser than near 1, mapping 1 to 0 caused 150 // a theoretically significant overshoot in the probability of returning 0. 151 // Instead of that, if we round up to 1, just try again. 152 // Getting 1 only happens 1/2⁵³ of the time, so most clients 153 // will not observe it anyway. 154 again: 155 f := float64(r.Uint64n(1<<53)) / (1 << 53) 156 if f == 1.0 { 157 goto again // resample; this branch is taken O(never) 158 } 159 return f 160 } 161 162 // Float32 returns, as a float32, a pseudo-random number in [0.0,1.0). 163 func (r *Rand) Float32() float32 { 164 // We do not want to return 1.0. 165 // This only happens 1/2²⁴ of the time (plus the 1/2⁵³ of the time in Float64). 166 again: 167 f := float32(r.Float64()) 168 if f == 1 { 169 goto again // resample; this branch is taken O(very rarely) 170 } 171 return f 172 } 173 174 // Perm returns, as a slice of n ints, a pseudo-random permutation of the integers [0,n). 175 func (r *Rand) Perm(n int) []int { 176 m := make([]int, n) 177 // In the following loop, the iteration when i=0 always swaps m[0] with m[0]. 178 // A change to remove this useless iteration is to assign 1 to i in the init 179 // statement. But Perm also effects r. Making this change will affect 180 // the final state of r. So this change can't be made for compatibility 181 // reasons for Go 1. 182 for i := 0; i < n; i++ { 183 j := r.Intn(i + 1) 184 m[i] = m[j] 185 m[j] = i 186 } 187 return m 188 } 189 190 // Shuffle pseudo-randomizes the order of elements. 191 // n is the number of elements. Shuffle panics if n < 0. 192 // swap swaps the elements with indexes i and j. 193 func (r *Rand) Shuffle(n int, swap func(i, j int)) { 194 if n < 0 { 195 panic("invalid argument to Shuffle") 196 } 197 198 // Fisher-Yates shuffle: https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle 199 // Shuffle really ought not be called with n that doesn't fit in 32 bits. 200 // Not only will it take a very long time, but with 2³¹! possible permutations, 201 // there's no way that any PRNG can have a big enough internal state to 202 // generate even a minuscule percentage of the possible permutations. 203 // Nevertheless, the right API signature accepts an int n, so handle it as best we can. 204 i := n - 1 205 for ; i > 1<<31-1-1; i-- { 206 j := int(r.Int63n(int64(i + 1))) 207 swap(i, j) 208 } 209 for ; i > 0; i-- { 210 j := int(r.Int31n(int32(i + 1))) 211 swap(i, j) 212 } 213 } 214 215 // Read generates len(p) random bytes and writes them into p. It 216 // always returns len(p) and a nil error. 217 // Read should not be called concurrently with any other Rand method unless 218 // the underlying source is a LockedSource. 219 func (r *Rand) Read(p []byte) (n int, err error) { 220 if lk, ok := r.src.(*LockedSource); ok { 221 return lk.Read(p, &r.readVal, &r.readPos) 222 } 223 return read(p, r.src, &r.readVal, &r.readPos) 224 } 225 226 func read(p []byte, src Source, readVal *uint64, readPos *int8) (n int, err error) { 227 pos := *readPos 228 val := *readVal 229 rng, _ := src.(*PCGSource) 230 for n = 0; n < len(p); n++ { 231 if pos == 0 { 232 if rng != nil { 233 val = rng.Uint64() 234 } else { 235 val = src.Uint64() 236 } 237 pos = 8 238 } 239 p[n] = byte(val) 240 val >>= 8 241 pos-- 242 } 243 *readPos = pos 244 *readVal = val 245 return 246 } 247 248 /* 249 * Top-level convenience functions 250 */ 251 252 var globalRand = New(&LockedSource{src: *NewSource(1).(*PCGSource)}) 253 254 // Type assert that globalRand's source is a LockedSource whose src is a PCGSource. 255 var _ PCGSource = globalRand.src.(*LockedSource).src 256 257 // Seed uses the provided seed value to initialize the default Source to a 258 // deterministic state. If Seed is not called, the generator behaves as 259 // if seeded by Seed(1). 260 // Seed, unlike the Rand.Seed method, is safe for concurrent use. 261 func Seed(seed uint64) { globalRand.Seed(seed) } 262 263 // Int63 returns a non-negative pseudo-random 63-bit integer as an int64 264 // from the default Source. 265 func Int63() int64 { return globalRand.Int63() } 266 267 // Uint32 returns a pseudo-random 32-bit value as a uint32 268 // from the default Source. 269 func Uint32() uint32 { return globalRand.Uint32() } 270 271 // Uint64 returns a pseudo-random 64-bit value as a uint64 272 // from the default Source. 273 func Uint64() uint64 { return globalRand.Uint64() } 274 275 // Int31 returns a non-negative pseudo-random 31-bit integer as an int32 276 // from the default Source. 277 func Int31() int32 { return globalRand.Int31() } 278 279 // Int returns a non-negative pseudo-random int from the default Source. 280 func Int() int { return globalRand.Int() } 281 282 // Int63n returns, as an int64, a non-negative pseudo-random number in [0,n) 283 // from the default Source. 284 // It panics if n <= 0. 285 func Int63n(n int64) int64 { return globalRand.Int63n(n) } 286 287 // Int31n returns, as an int32, a non-negative pseudo-random number in [0,n) 288 // from the default Source. 289 // It panics if n <= 0. 290 func Int31n(n int32) int32 { return globalRand.Int31n(n) } 291 292 // Intn returns, as an int, a non-negative pseudo-random number in [0,n) 293 // from the default Source. 294 // It panics if n <= 0. 295 func Intn(n int) int { return globalRand.Intn(n) } 296 297 // Float64 returns, as a float64, a pseudo-random number in [0.0,1.0) 298 // from the default Source. 299 func Float64() float64 { return globalRand.Float64() } 300 301 // Float32 returns, as a float32, a pseudo-random number in [0.0,1.0) 302 // from the default Source. 303 func Float32() float32 { return globalRand.Float32() } 304 305 // Perm returns, as a slice of n ints, a pseudo-random permutation of the integers [0,n) 306 // from the default Source. 307 func Perm(n int) []int { return globalRand.Perm(n) } 308 309 // Shuffle pseudo-randomizes the order of elements using the default Source. 310 // n is the number of elements. Shuffle panics if n < 0. 311 // swap swaps the elements with indexes i and j. 312 func Shuffle(n int, swap func(i, j int)) { globalRand.Shuffle(n, swap) } 313 314 // Read generates len(p) random bytes from the default Source and 315 // writes them into p. It always returns len(p) and a nil error. 316 // Read, unlike the Rand.Read method, is safe for concurrent use. 317 func Read(p []byte) (n int, err error) { return globalRand.Read(p) } 318 319 // NormFloat64 returns a normally distributed float64 in the range 320 // [-math.MaxFloat64, +math.MaxFloat64] with 321 // standard normal distribution (mean = 0, stddev = 1) 322 // from the default Source. 323 // To produce a different normal distribution, callers can 324 // adjust the output using: 325 // 326 // sample = NormFloat64() * desiredStdDev + desiredMean 327 func NormFloat64() float64 { return globalRand.NormFloat64() } 328 329 // ExpFloat64 returns an exponentially distributed float64 in the range 330 // (0, +math.MaxFloat64] with an exponential distribution whose rate parameter 331 // (lambda) is 1 and whose mean is 1/lambda (1) from the default Source. 332 // To produce a distribution with a different rate parameter, 333 // callers can adjust the output using: 334 // 335 // sample = ExpFloat64() / desiredRateParameter 336 func ExpFloat64() float64 { return globalRand.ExpFloat64() } 337 338 // LockedSource is an implementation of Source that is concurrency-safe. 339 // A Rand using a LockedSource is safe for concurrent use. 340 // 341 // The zero value of LockedSource is valid, but should be seeded before use. 342 type LockedSource struct { 343 lk sync.Mutex 344 src PCGSource 345 } 346 347 func (s *LockedSource) Uint64() (n uint64) { 348 s.lk.Lock() 349 n = s.src.Uint64() 350 s.lk.Unlock() 351 return 352 } 353 354 func (s *LockedSource) Seed(seed uint64) { 355 s.lk.Lock() 356 s.src.Seed(seed) 357 s.lk.Unlock() 358 } 359 360 // seedPos implements Seed for a LockedSource without a race condiiton. 361 func (s *LockedSource) seedPos(seed uint64, readPos *int8) { 362 s.lk.Lock() 363 s.src.Seed(seed) 364 *readPos = 0 365 s.lk.Unlock() 366 } 367 368 // Read implements Read for a LockedSource. 369 func (s *LockedSource) Read(p []byte, readVal *uint64, readPos *int8) (n int, err error) { 370 s.lk.Lock() 371 n, err = read(p, &s.src, readVal, readPos) 372 s.lk.Unlock() 373 return 374 }