@@ -17,7 +17,10 @@ limitations under the License.
1717package config
1818
1919import (
20+ "crypto/sha256"
21+ "encoding/binary"
2022 "fmt"
23+ "io"
2124 "io/fs"
2225 "io/ioutil"
2326 "math"
@@ -34,8 +37,10 @@ import (
3437 "k8s.io/klog/v2"
3538)
3639
40+ var globalRand * rand.Rand
41+
3742func init () {
38- rand .Seed ( time .Now ().UnixNano ())
43+ globalRand = rand .New ( rand . NewSource ( time .Now ().UnixNano () ))
3944}
4045
4146// GetFuncs returns map of names to functions, that are supported by template provider.
@@ -60,6 +65,7 @@ func GetFuncs(fsys fs.FS) template.FuncMap {
6065 "MultiplyFloat" : multiplyFloat ,
6166 "MultiplyInt" : multiplyInt ,
6267 "RandData" : randData ,
68+ "RandDataWithSeed" : randDataWithSeed ,
6369 "RandInt" : randInt ,
6470 "RandIntRange" : randIntRange ,
6571 "Seq" : seq ,
@@ -108,9 +114,29 @@ func toFloat64(val interface{}) float64 {
108114
109115// randData returns pseudo-random string of i length.
110116func randData (i interface {}) string {
111- const alphabet = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
112117 typedI := int (toFloat64 (i ))
113- b := make ([]byte , typedI )
118+ return randString (globalRand , typedI )
119+ }
120+
121+ // randData returns pseudo-random string of i length with a provided seed to allow deterministic result.
122+ func randDataWithSeed (i , j interface {}) string {
123+ typedI := int (toFloat64 (i ))
124+ if typedI == 0 {
125+ return ""
126+ }
127+ typedJ := j .(string )
128+ h := sha256 .New ()
129+ _ , err := io .WriteString (h , typedJ )
130+ if err != nil {
131+ panic (fmt .Sprintf ("failed to write %q to sha256 hash" , typedJ ))
132+ }
133+ seed := int64 (binary .BigEndian .Uint64 (h .Sum (nil )))
134+ return randString (rand .New (rand .NewSource (seed )), typedI )
135+ }
136+
137+ func randString (rand * rand.Rand , length int ) string {
138+ const alphabet = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
139+ b := make ([]byte , length )
114140 for i := range b {
115141 b [i ] = alphabet [rand .Intn (len (alphabet ))]
116142 }
@@ -120,7 +146,7 @@ func randData(i interface{}) string {
120146// randInt returns pseudo-random int in [0, i].
121147func randInt (i interface {}) int {
122148 typedI := int (toFloat64 (i ))
123- return rand .Intn (typedI + 1 )
149+ return globalRand .Intn (typedI + 1 )
124150}
125151
126152// randIntRange returns pseudo-random int in [i, j].
@@ -131,7 +157,7 @@ func randIntRange(i, j interface{}) int {
131157 if typedI >= typedJ {
132158 return typedI
133159 }
134- return typedI + rand .Intn (typedJ - typedI + 1 )
160+ return typedI + globalRand .Intn (typedJ - typedI + 1 )
135161}
136162
137163func addInt (numbers ... interface {}) int {
0 commit comments