github.com/andy2046/gopie@v0.7.0/pkg/randomsequence/randomseq.go (about) 1 // Package randomsequence implements quadratic residues based random sequence. 2 package randomsequence 3 4 // https://preshing.com/20121224/how-to-generate-a-sequence-of-unique-random-integers 5 6 // Random represents the random sequence. 7 type Random struct { 8 index uint32 9 offset uint32 10 } 11 12 const ( 13 prime uint32 = 4294967291 14 primeBy2 uint32 = prime / 2 15 ) 16 17 // New creates a random sequence with the seed provided. 18 func New(seedBase, seedOffset uint32) *Random { 19 return &Random{ 20 index: permute(permute(seedBase) + 0x682f0161), 21 offset: permute(permute(seedOffset) + 0x46790905), 22 } 23 } 24 25 // Next returns next random number. 26 func (r *Random) Next() uint32 { 27 i := r.index 28 r.index++ 29 return permute((permute(i) + r.offset) ^ 0x5bf03635) 30 } 31 32 func permute(x uint32) uint32 { 33 if x >= prime { 34 // The 5 integers in the range [4294967291, 2^32] are mapped to themselves. 35 return x 36 } 37 38 residue := uint32(uint64(x) * uint64(x) % uint64(prime)) 39 if x > primeBy2 { 40 return prime - residue 41 } 42 return residue 43 }