rand_int.go 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. package utils
  2. import (
  3. "crypto/rand"
  4. "encoding/binary"
  5. "fmt"
  6. )
  7. // 使用真随机数 实现摇摇乐
  8. // 对数组随机生成 指定次数:10万次 (不得低于10万次)
  9. func TrueRandomForLotteryDraw(int64Slice []int64, times int) (map[int64]int, int64, int, error) {
  10. if times < 100000 {
  11. times = 100000
  12. }
  13. var randInt64List []int64
  14. countMap := make(map[int64]int)
  15. for i := 0; i < times; i++ {
  16. randInt64, err := TrueRandomInt64Slice(int64Slice)
  17. if err != nil {
  18. return countMap, 0, 0, err
  19. }
  20. randInt64List = append(randInt64List, randInt64)
  21. }
  22. var maxTimes int = 0
  23. var maxId int64 = 0
  24. for _, num := range randInt64List {
  25. countMap[num]++
  26. if countMap[num] > maxTimes {
  27. maxTimes = countMap[num]
  28. maxId = num
  29. }
  30. }
  31. return countMap, maxId, maxTimes, nil
  32. }
  33. // 随机int64 切片
  34. func TrueRandomInt64Slice(ids []int64) (int64, error) {
  35. if len(ids) == 0 {
  36. return 0, fmt.Errorf("len ids is zero")
  37. }
  38. if len(ids) == 1 {
  39. return ids[0], nil
  40. }
  41. randInt, err := TrueRandomInt(0, len(ids)-1)
  42. return ids[randInt], err
  43. }
  44. // 生成指定范围内的真随机数
  45. func TrueRandomInt(min, max int) (int, error) {
  46. if min > max {
  47. return 0, fmt.Errorf("min cannot be greater than max")
  48. }
  49. // 生成随机字节
  50. var n uint32
  51. err := binary.Read(rand.Reader, binary.BigEndian, &n)
  52. if err != nil {
  53. return 0, err
  54. }
  55. // 映射到指定范围
  56. rangeSize := uint32(max - min + 1)
  57. result := min + int(n%rangeSize)
  58. return result, nil
  59. }