github.com/sagernet/quic-go@v0.43.1-beta.1/internal/utils/rand.go (about)

     1  package utils
     2  
     3  import (
     4  	"crypto/rand"
     5  	"encoding/binary"
     6  )
     7  
     8  // Rand is a wrapper around crypto/rand that adds some convenience functions known from math/rand.
     9  type Rand struct {
    10  	buf [4]byte
    11  }
    12  
    13  func (r *Rand) Int31() int32 {
    14  	rand.Read(r.buf[:])
    15  	return int32(binary.BigEndian.Uint32(r.buf[:]) & ^uint32(1<<31))
    16  }
    17  
    18  // copied from the standard library math/rand implementation of Int63n
    19  func (r *Rand) Int31n(n int32) int32 {
    20  	if n&(n-1) == 0 { // n is power of two, can mask
    21  		return r.Int31() & (n - 1)
    22  	}
    23  	max := int32((1 << 31) - 1 - (1<<31)%uint32(n))
    24  	v := r.Int31()
    25  	for v > max {
    26  		v = r.Int31()
    27  	}
    28  	return v % n
    29  }