-
Notifications
You must be signed in to change notification settings - Fork 7
/
rand.go
153 lines (137 loc) · 3.56 KB
/
rand.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
package math
import (
crand "crypto/rand"
"encoding/hex"
"math/rand"
"time"
)
// RandBetween rand a num between min to max
func RandBetween(min, max int) int {
if min >= max || max == 0 {
return max
}
r := rand.New(rand.NewSource(time.Now().UnixNano()))
random := r.Intn(max-min) + min
return random
}
// GenerateRandomBytes returns securely generated random bytes.
// It will return an error if the system's secure random
// number generator fails to function correctly, in which
// GenerateRandomBytes case the caller should not continue.
func GenerateRandomBytes(n int) ([]byte, error) {
b := make([]byte, n)
_, err := crand.Read(b)
// Note that err == nil only if we read len(b) bytes.
if err != nil {
return nil, err
}
return b, nil
}
// GenerateRandomString returns a URL-safe, base64 encoded
// securely generated random string.
// It will return an error if the system's secure random
// number generator fails to function correctly, in which
// GenerateRandomString case the caller should not continue.
func GenerateRandomString(s int) (string, error) {
b, err := GenerateRandomBytes(s)
return hex.EncodeToString(b), err
}
// SliceOutOfOrder 乱序切片
func SliceOutOfOrder(in []string) []string {
rr := rand.New(rand.NewSource(time.Now().UnixNano()))
l := len(in)
for i := l - 1; i > 0; i-- {
r := rr.Intn(i)
in[r], in[i] = in[i], in[r]
}
return in
}
// SliceOutOfOrderByInt 乱序切片
func SliceOutOfOrderByInt(in []uint64) []uint64 {
rr := rand.New(rand.NewSource(time.Now().UnixNano()))
l := len(in)
for i := l - 1; i > 0; i-- {
r := rr.Intn(i)
in[r], in[i] = in[i], in[r]
}
return in
}
type valueWeightItem struct {
weight uint32
value uint64
}
// ValueWeightPair 权值对,根据权重随机一个值出来
type ValueWeightPair struct {
allweight uint32
valuelist []valueWeightItem
}
// NewValueWeightPair new value weight pair
func NewValueWeightPair() *ValueWeightPair {
vwp := new(ValueWeightPair)
vwp.valuelist = make([]valueWeightItem, 0)
return vwp
}
// Add add weight
func (v *ValueWeightPair) Add(weight uint32, value uint64) {
valueinfo := valueWeightItem{}
valueinfo.weight = weight
valueinfo.value = value
v.valuelist = append(v.valuelist, valueinfo)
v.allweight += weight
}
// Random random a num
func (v *ValueWeightPair) Random() uint64 {
if v.allweight > 0 {
r := rand.New(rand.NewSource(time.Now().UnixNano()))
randvalue := uint32(r.Intn(int(v.allweight)))
addweight := uint32(0)
for i := 0; i < len(v.valuelist); i++ {
addweight += v.valuelist[i].weight
if randvalue <= addweight {
return v.valuelist[i].value
}
}
}
return 0
}
// RandWeight 根据权重列表随机出一个结果,返回命中下标
func RandWeight(weight []uint32) uint32 {
total := uint32(0)
for _, v := range weight {
total += v
}
r := rand.New(rand.NewSource(time.Now().UnixNano()))
randvalue := uint32(r.Intn(int(total)))
tmp := uint32(0)
for i, v := range weight {
tmp += v
if tmp >= randvalue {
return uint32(i)
}
}
return 0
}
// UtilWeightInterface infterface
type UtilWeightInterface interface {
GetWeight() uint32
}
// RandWeightStruct 根据权重列表随机出一个结果,返回命中下标
func RandWeightStruct(weight []UtilWeightInterface) interface{} {
if len(weight) == 0 {
return nil
}
total := uint32(0)
for _, v := range weight {
total += v.GetWeight()
}
r := rand.New(rand.NewSource(time.Now().UnixNano()))
randvalue := uint32(r.Intn(int(total)))
tmp := uint32(0)
for i, v := range weight {
tmp += v.GetWeight()
if tmp <= randvalue {
return weight[i]
}
}
return weight[0]
}