github.com/v2fly/v2ray-core/v5@v5.16.2-0.20240507031116-8191faa6e095/common/dice/dice.go (about) 1 // Package dice contains common functions to generate random number. 2 // It also initialize math/rand with the time in seconds at launch time. 3 package dice 4 5 import ( 6 crand "crypto/rand" 7 "io" 8 "math/big" 9 "math/rand" 10 "time" 11 12 "github.com/v2fly/v2ray-core/v5/common" 13 ) 14 15 // Roll returns a non-negative number between 0 (inclusive) and n (exclusive). 16 func Roll(n int) int { 17 if n == 1 { 18 return 0 19 } 20 return rand.Intn(n) 21 } 22 23 // RollWith returns a non-negative number between 0 (inclusive) and n (exclusive). 24 // Use random as the random source, if read fails, it panics. 25 func RollWith(n int, random io.Reader) int { 26 if n == 1 { 27 return 0 28 } 29 mrand, err := crand.Int(random, big.NewInt(int64(n))) 30 common.Must(err) 31 return int(mrand.Int64()) 32 } 33 34 // Roll returns a non-negative number between 0 (inclusive) and n (exclusive). 35 func RollDeterministic(n int, seed int64) int { 36 if n == 1 { 37 return 0 38 } 39 return rand.New(rand.NewSource(seed)).Intn(n) 40 } 41 42 // RollUint16 returns a random uint16 value. 43 func RollUint16() uint16 { 44 return uint16(rand.Int63() >> 47) 45 } 46 47 func RollUint64() uint64 { 48 return rand.Uint64() 49 } 50 51 func NewDeterministicDice(seed int64) *DeterministicDice { 52 return &DeterministicDice{rand.New(rand.NewSource(seed))} 53 } 54 55 type DeterministicDice struct { 56 *rand.Rand 57 } 58 59 func (dd *DeterministicDice) Roll(n int) int { 60 if n == 1 { 61 return 0 62 } 63 return dd.Intn(n) 64 } 65 66 func init() { 67 rand.Seed(time.Now().Unix()) 68 }