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  }