dice.go 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  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. import (
  5. crand "crypto/rand"
  6. "io"
  7. "math/big"
  8. "math/rand"
  9. "time"
  10. "github.com/v2fly/v2ray-core/v5/common"
  11. )
  12. // Roll returns a non-negative number between 0 (inclusive) and n (exclusive).
  13. func Roll(n int) int {
  14. if n == 1 {
  15. return 0
  16. }
  17. return rand.Intn(n)
  18. }
  19. // RollWith returns a non-negative number between 0 (inclusive) and n (exclusive).
  20. // Use random as the random source, if read fails, it panics.
  21. func RollWith(n int, random io.Reader) int {
  22. if n == 1 {
  23. return 0
  24. }
  25. mrand, err := crand.Int(random, big.NewInt(int64(n)))
  26. common.Must(err)
  27. return int(mrand.Int64())
  28. }
  29. // Roll returns a non-negative number between 0 (inclusive) and n (exclusive).
  30. func RollDeterministic(n int, seed int64) int {
  31. if n == 1 {
  32. return 0
  33. }
  34. return rand.New(rand.NewSource(seed)).Intn(n)
  35. }
  36. // RollUint16 returns a random uint16 value.
  37. func RollUint16() uint16 {
  38. return uint16(rand.Int63() >> 47)
  39. }
  40. func RollUint64() uint64 {
  41. return rand.Uint64()
  42. }
  43. func NewDeterministicDice(seed int64) *DeterministicDice {
  44. return &DeterministicDice{rand.New(rand.NewSource(seed))}
  45. }
  46. type DeterministicDice struct {
  47. *rand.Rand
  48. }
  49. func (dd *DeterministicDice) Roll(n int) int {
  50. if n == 1 {
  51. return 0
  52. }
  53. return dd.Intn(n)
  54. }
  55. func init() {
  56. rand.Seed(time.Now().Unix())
  57. }