github.com/xaionaro-go/rand@v0.0.0-20191005105903-aba1befc54a5/mathrand/read_autogenerated.go (about)

     1  package mathrand
     2  
     3  import (
     4  	"unsafe"
     5  )
     6  
     7  // This file was automatically generated by github.com/xaionaro-go/rand/internal/autogen
     8  
     9  // ReadUint64AddRotateMultiply is an analog of math/rand.Read. This random
    10  // numbers could easily be predicted (it's not an analog of crypto/rand.Read).
    11  //
    12  // Applied PRNG method:
    13  // Uint64AddRotateMultiply is a fast analog of `math/rand.Uint64`.
    14  //
    15  // The reliability on statistical tests of this method is unknown. This is
    16  // improved LCG method, so see also Uint64MultiplyAdd.
    17  func (prng *PRNG) ReadUint64AddRotateMultiply(b []byte) (l int, err error) {
    18  	l = len(b)
    19  	s := (uintptr)((unsafe.Pointer)(&b[0]))
    20  	p := s
    21  	e := s + uintptr(l)
    22  	{
    23  		state64Temp0 := prng.state64[0]
    24  		for f := e - 8; p <= f; p += 8 {
    25  			state64Temp0 += primeNumber64bit1
    26  			state64Temp0 = rotateLeft64(state64Temp0, 32)
    27  			state64Temp0 *= primeNumber64bit0
    28  			*(*uint64)((unsafe.Pointer)(p)) = state64Temp0
    29  		}
    30  		prng.state64[0] = state64Temp0
    31  	}
    32  
    33  	if e-p == 0 {
    34  		return
    35  	}
    36  	rest := prng.Uint64AddRotateMultiply()
    37  	if e-p >= 4 {
    38  		*(*uint32)((unsafe.Pointer)(p)) = uint32(rest)
    39  		rest >>= 32
    40  		p += 4
    41  	}
    42  	if e-p >= 2 {
    43  		*(*uint16)((unsafe.Pointer)(p)) = uint16(rest)
    44  		rest >>= 16
    45  		p += 2
    46  	}
    47  	if e-p >= 1 {
    48  		*(*uint8)((unsafe.Pointer)(p)) = uint8(rest)
    49  	}
    50  	return
    51  }
    52  
    53  // XORReadUint64AddRotateMultiply XORs argument "b" with a pseudo-random value.
    54  // The result is the same (but faster) as:
    55  //
    56  // 	x := make([]byte, len(b))
    57  // 	mathrand.ReadUint64AddRotateMultiply(x)
    58  // 	for i := range b {
    59  // 		b[i] ^= x[i]
    60  // 	}
    61  func (prng *PRNG) XORReadUint64AddRotateMultiply(b []byte) (l int, err error) {
    62  	l = len(b)
    63  	s := (uintptr)((unsafe.Pointer)(&b[0]))
    64  	p := s
    65  	e := s + uintptr(l)
    66  	{
    67  		state64Temp0 := prng.state64[0]
    68  		for f := e - 8; p <= f; p += 8 {
    69  			state64Temp0 += primeNumber64bit1
    70  			state64Temp0 = rotateLeft64(state64Temp0, 32)
    71  			state64Temp0 *= primeNumber64bit0
    72  			*(*uint64)((unsafe.Pointer)(p)) ^= state64Temp0
    73  		}
    74  		prng.state64[0] = state64Temp0
    75  	}
    76  
    77  	if e-p == 0 {
    78  		return
    79  	}
    80  	rest := prng.Uint64AddRotateMultiply()
    81  	if e-p >= 4 {
    82  		*(*uint32)((unsafe.Pointer)(p)) ^= uint32(rest)
    83  		rest >>= 32
    84  		p += 4
    85  	}
    86  	if e-p >= 2 {
    87  		*(*uint16)((unsafe.Pointer)(p)) ^= uint16(rest)
    88  		rest >>= 16
    89  		p += 2
    90  	}
    91  	if e-p >= 1 {
    92  		*(*uint8)((unsafe.Pointer)(p)) ^= uint8(rest)
    93  	}
    94  	return
    95  }
    96  
    97  // ReadUint64AddRotateMultiplyWithReseed is an analog of math/rand.Read. This random
    98  // numbers could easily be predicted (it's not an analog of crypto/rand.Read).
    99  //
   100  // "Reseed" forces to use a new seed (generated using XORShift method) on setting value to
   101  // a pointer `& 0xff < 8`. Sometimes it allows to improve randomness of random numbers with a
   102  // small performance impact.
   103  // This method makes sense only if len(b) is large enough (>= 256 bytes).
   104  // Otherwise it could affect strongly performance or it will not improve the randomness.
   105  //
   106  // Applied PRNG method:
   107  // Uint64AddRotateMultiply is a fast analog of `math/rand.Uint64`.
   108  //
   109  // The reliability on statistical tests of this method is unknown. This is
   110  // improved LCG method, so see also Uint64MultiplyAdd.
   111  func (prng *PRNG) ReadUint64AddRotateMultiplyWithReseed(b []byte) (l int, err error) {
   112  	l = len(b)
   113  	s := (uintptr)((unsafe.Pointer)(&b[0]))
   114  	p := s
   115  	e := s + uintptr(l)
   116  	{
   117  		state64Temp0 := prng.state64[0]
   118  		for f := e - 8; p <= f; p += 8 {
   119  			state64Temp0 += primeNumber64bit1
   120  			state64Temp0 = rotateLeft64(state64Temp0, 32)
   121  			state64Temp0 *= primeNumber64bit0
   122  			*(*uint64)((unsafe.Pointer)(p)) = state64Temp0
   123  			if p&0xff < 8 {
   124  				continue
   125  			}
   126  			state64Temp0 = xorShift64(state64Temp0 ^ primeNumber64bit0)
   127  		}
   128  		prng.state64[0] = state64Temp0
   129  	}
   130  
   131  	if e-p == 0 {
   132  		return
   133  	}
   134  	rest := prng.Uint64AddRotateMultiply()
   135  	if e-p >= 4 {
   136  		*(*uint32)((unsafe.Pointer)(p)) = uint32(rest)
   137  		rest >>= 32
   138  		p += 4
   139  	}
   140  	if e-p >= 2 {
   141  		*(*uint16)((unsafe.Pointer)(p)) = uint16(rest)
   142  		rest >>= 16
   143  		p += 2
   144  	}
   145  	if e-p >= 1 {
   146  		*(*uint8)((unsafe.Pointer)(p)) = uint8(rest)
   147  	}
   148  	return
   149  }
   150  
   151  // XORReadUint64AddRotateMultiplyWithReseed XORs argument "b" with a pseudo-random value.
   152  // The result is the same (but faster) as:
   153  //
   154  // 	x := make([]byte, len(b))
   155  // 	mathrand.ReadUint64AddRotateMultiplyWithReseed(x)
   156  // 	for i := range b {
   157  // 		b[i] ^= x[i]
   158  // 	}
   159  func (prng *PRNG) XORReadUint64AddRotateMultiplyWithReseed(b []byte) (l int, err error) {
   160  	l = len(b)
   161  	s := (uintptr)((unsafe.Pointer)(&b[0]))
   162  	p := s
   163  	e := s + uintptr(l)
   164  	{
   165  		state64Temp0 := prng.state64[0]
   166  		for f := e - 8; p <= f; p += 8 {
   167  			state64Temp0 += primeNumber64bit1
   168  			state64Temp0 = rotateLeft64(state64Temp0, 32)
   169  			state64Temp0 *= primeNumber64bit0
   170  			*(*uint64)((unsafe.Pointer)(p)) ^= state64Temp0
   171  			if p&0xff < 8 {
   172  				continue
   173  			}
   174  			state64Temp0 = xorShift64(state64Temp0 ^ primeNumber64bit0)
   175  		}
   176  		prng.state64[0] = state64Temp0
   177  	}
   178  
   179  	if e-p == 0 {
   180  		return
   181  	}
   182  	rest := prng.Uint64AddRotateMultiply()
   183  	if e-p >= 4 {
   184  		*(*uint32)((unsafe.Pointer)(p)) ^= uint32(rest)
   185  		rest >>= 32
   186  		p += 4
   187  	}
   188  	if e-p >= 2 {
   189  		*(*uint16)((unsafe.Pointer)(p)) ^= uint16(rest)
   190  		rest >>= 16
   191  		p += 2
   192  	}
   193  	if e-p >= 1 {
   194  		*(*uint8)((unsafe.Pointer)(p)) ^= uint8(rest)
   195  	}
   196  	return
   197  }
   198  
   199  // ReadUint64AddNRotateMultiply is an analog of math/rand.Read. This random
   200  // numbers could easily be predicted (it's not an analog of crypto/rand.Read).
   201  //
   202  // Applied PRNG method:
   203  // Uint64AddNRotateMultiply is a fast analog of `math/rand.Uint64`.
   204  //
   205  // The reliability on statistical tests of this method is unknown. This is
   206  // improved LCG method, so see also Uint64MultiplyAdd.
   207  func (prng *PRNG) ReadUint64AddNRotateMultiply(b []byte) (l int, err error) {
   208  	l = len(b)
   209  	s := (uintptr)((unsafe.Pointer)(&b[0]))
   210  	p := s
   211  	e := s + uintptr(l)
   212  	{
   213  		state64Temp0 := prng.state64[0]
   214  		for f := e - 8; p <= f; p += 8 {
   215  			state64Temp0 += primeNumber64bit1
   216  			r := 28 + int(state64Temp0&0x7)
   217  			state64Temp0 = rotateLeft64(state64Temp0, r)
   218  			state64Temp0 *= primeNumber64bit0
   219  			*(*uint64)((unsafe.Pointer)(p)) = state64Temp0
   220  		}
   221  		prng.state64[0] = state64Temp0
   222  	}
   223  
   224  	if e-p == 0 {
   225  		return
   226  	}
   227  	rest := prng.Uint64AddNRotateMultiply()
   228  	if e-p >= 4 {
   229  		*(*uint32)((unsafe.Pointer)(p)) = uint32(rest)
   230  		rest >>= 32
   231  		p += 4
   232  	}
   233  	if e-p >= 2 {
   234  		*(*uint16)((unsafe.Pointer)(p)) = uint16(rest)
   235  		rest >>= 16
   236  		p += 2
   237  	}
   238  	if e-p >= 1 {
   239  		*(*uint8)((unsafe.Pointer)(p)) = uint8(rest)
   240  	}
   241  	return
   242  }
   243  
   244  // XORReadUint64AddNRotateMultiply XORs argument "b" with a pseudo-random value.
   245  // The result is the same (but faster) as:
   246  //
   247  // 	x := make([]byte, len(b))
   248  // 	mathrand.ReadUint64AddNRotateMultiply(x)
   249  // 	for i := range b {
   250  // 		b[i] ^= x[i]
   251  // 	}
   252  func (prng *PRNG) XORReadUint64AddNRotateMultiply(b []byte) (l int, err error) {
   253  	l = len(b)
   254  	s := (uintptr)((unsafe.Pointer)(&b[0]))
   255  	p := s
   256  	e := s + uintptr(l)
   257  	{
   258  		state64Temp0 := prng.state64[0]
   259  		for f := e - 8; p <= f; p += 8 {
   260  			state64Temp0 += primeNumber64bit1
   261  			r := 28 + int(state64Temp0&0x7)
   262  			state64Temp0 = rotateLeft64(state64Temp0, r)
   263  			state64Temp0 *= primeNumber64bit0
   264  			*(*uint64)((unsafe.Pointer)(p)) ^= state64Temp0
   265  		}
   266  		prng.state64[0] = state64Temp0
   267  	}
   268  
   269  	if e-p == 0 {
   270  		return
   271  	}
   272  	rest := prng.Uint64AddNRotateMultiply()
   273  	if e-p >= 4 {
   274  		*(*uint32)((unsafe.Pointer)(p)) ^= uint32(rest)
   275  		rest >>= 32
   276  		p += 4
   277  	}
   278  	if e-p >= 2 {
   279  		*(*uint16)((unsafe.Pointer)(p)) ^= uint16(rest)
   280  		rest >>= 16
   281  		p += 2
   282  	}
   283  	if e-p >= 1 {
   284  		*(*uint8)((unsafe.Pointer)(p)) ^= uint8(rest)
   285  	}
   286  	return
   287  }
   288  
   289  // ReadUint64AddNRotateMultiplyWithReseed is an analog of math/rand.Read. This random
   290  // numbers could easily be predicted (it's not an analog of crypto/rand.Read).
   291  //
   292  // "Reseed" forces to use a new seed (generated using XORShift method) on setting value to
   293  // a pointer `& 0xff < 8`. Sometimes it allows to improve randomness of random numbers with a
   294  // small performance impact.
   295  // This method makes sense only if len(b) is large enough (>= 256 bytes).
   296  // Otherwise it could affect strongly performance or it will not improve the randomness.
   297  //
   298  // Applied PRNG method:
   299  // Uint64AddNRotateMultiply is a fast analog of `math/rand.Uint64`.
   300  //
   301  // The reliability on statistical tests of this method is unknown. This is
   302  // improved LCG method, so see also Uint64MultiplyAdd.
   303  func (prng *PRNG) ReadUint64AddNRotateMultiplyWithReseed(b []byte) (l int, err error) {
   304  	l = len(b)
   305  	s := (uintptr)((unsafe.Pointer)(&b[0]))
   306  	p := s
   307  	e := s + uintptr(l)
   308  	{
   309  		state64Temp0 := prng.state64[0]
   310  		for f := e - 8; p <= f; p += 8 {
   311  			state64Temp0 += primeNumber64bit1
   312  			r := 28 + int(state64Temp0&0x7)
   313  			state64Temp0 = rotateLeft64(state64Temp0, r)
   314  			state64Temp0 *= primeNumber64bit0
   315  			*(*uint64)((unsafe.Pointer)(p)) = state64Temp0
   316  			if p&0xff < 8 {
   317  				continue
   318  			}
   319  			state64Temp0 = xorShift64(state64Temp0 ^ primeNumber64bit0)
   320  		}
   321  		prng.state64[0] = state64Temp0
   322  	}
   323  
   324  	if e-p == 0 {
   325  		return
   326  	}
   327  	rest := prng.Uint64AddNRotateMultiply()
   328  	if e-p >= 4 {
   329  		*(*uint32)((unsafe.Pointer)(p)) = uint32(rest)
   330  		rest >>= 32
   331  		p += 4
   332  	}
   333  	if e-p >= 2 {
   334  		*(*uint16)((unsafe.Pointer)(p)) = uint16(rest)
   335  		rest >>= 16
   336  		p += 2
   337  	}
   338  	if e-p >= 1 {
   339  		*(*uint8)((unsafe.Pointer)(p)) = uint8(rest)
   340  	}
   341  	return
   342  }
   343  
   344  // XORReadUint64AddNRotateMultiplyWithReseed XORs argument "b" with a pseudo-random value.
   345  // The result is the same (but faster) as:
   346  //
   347  // 	x := make([]byte, len(b))
   348  // 	mathrand.ReadUint64AddNRotateMultiplyWithReseed(x)
   349  // 	for i := range b {
   350  // 		b[i] ^= x[i]
   351  // 	}
   352  func (prng *PRNG) XORReadUint64AddNRotateMultiplyWithReseed(b []byte) (l int, err error) {
   353  	l = len(b)
   354  	s := (uintptr)((unsafe.Pointer)(&b[0]))
   355  	p := s
   356  	e := s + uintptr(l)
   357  	{
   358  		state64Temp0 := prng.state64[0]
   359  		for f := e - 8; p <= f; p += 8 {
   360  			state64Temp0 += primeNumber64bit1
   361  			r := 28 + int(state64Temp0&0x7)
   362  			state64Temp0 = rotateLeft64(state64Temp0, r)
   363  			state64Temp0 *= primeNumber64bit0
   364  			*(*uint64)((unsafe.Pointer)(p)) ^= state64Temp0
   365  			if p&0xff < 8 {
   366  				continue
   367  			}
   368  			state64Temp0 = xorShift64(state64Temp0 ^ primeNumber64bit0)
   369  		}
   370  		prng.state64[0] = state64Temp0
   371  	}
   372  
   373  	if e-p == 0 {
   374  		return
   375  	}
   376  	rest := prng.Uint64AddNRotateMultiply()
   377  	if e-p >= 4 {
   378  		*(*uint32)((unsafe.Pointer)(p)) ^= uint32(rest)
   379  		rest >>= 32
   380  		p += 4
   381  	}
   382  	if e-p >= 2 {
   383  		*(*uint16)((unsafe.Pointer)(p)) ^= uint16(rest)
   384  		rest >>= 16
   385  		p += 2
   386  	}
   387  	if e-p >= 1 {
   388  		*(*uint8)((unsafe.Pointer)(p)) ^= uint8(rest)
   389  	}
   390  	return
   391  }
   392  
   393  // ReadUint64MultiplyAdd is an analog of math/rand.Read. This random
   394  // numbers could easily be predicted (it's not an analog of crypto/rand.Read).
   395  //
   396  // Applied PRNG method:
   397  // Uint64MultiplyAdd is a fast (but week) analog of `math/rand.Uint64`.
   398  //
   399  // See also: https://en.wikipedia.org/wiki/Linear_congruential_generator
   400  func (prng *PRNG) ReadUint64MultiplyAdd(b []byte) (l int, err error) {
   401  	l = len(b)
   402  	s := (uintptr)((unsafe.Pointer)(&b[0]))
   403  	p := s
   404  	e := s + uintptr(l)
   405  	{
   406  		state64Temp0 := prng.state64[0]
   407  		for f := e - 8; p <= f; p += 8 {
   408  			state64Temp0 *= primeNumber64bit0
   409  			state64Temp0 += primeNumber64bit1
   410  			*(*uint64)((unsafe.Pointer)(p)) = state64Temp0
   411  		}
   412  		prng.state64[0] = state64Temp0
   413  	}
   414  
   415  	if e-p == 0 {
   416  		return
   417  	}
   418  	rest := prng.Uint64MultiplyAdd()
   419  	if e-p >= 4 {
   420  		*(*uint32)((unsafe.Pointer)(p)) = uint32(rest)
   421  		rest >>= 32
   422  		p += 4
   423  	}
   424  	if e-p >= 2 {
   425  		*(*uint16)((unsafe.Pointer)(p)) = uint16(rest)
   426  		rest >>= 16
   427  		p += 2
   428  	}
   429  	if e-p >= 1 {
   430  		*(*uint8)((unsafe.Pointer)(p)) = uint8(rest)
   431  	}
   432  	return
   433  }
   434  
   435  // XORReadUint64MultiplyAdd XORs argument "b" with a pseudo-random value.
   436  // The result is the same (but faster) as:
   437  //
   438  // 	x := make([]byte, len(b))
   439  // 	mathrand.ReadUint64MultiplyAdd(x)
   440  // 	for i := range b {
   441  // 		b[i] ^= x[i]
   442  // 	}
   443  func (prng *PRNG) XORReadUint64MultiplyAdd(b []byte) (l int, err error) {
   444  	l = len(b)
   445  	s := (uintptr)((unsafe.Pointer)(&b[0]))
   446  	p := s
   447  	e := s + uintptr(l)
   448  	{
   449  		state64Temp0 := prng.state64[0]
   450  		for f := e - 8; p <= f; p += 8 {
   451  			state64Temp0 *= primeNumber64bit0
   452  			state64Temp0 += primeNumber64bit1
   453  			*(*uint64)((unsafe.Pointer)(p)) ^= state64Temp0
   454  		}
   455  		prng.state64[0] = state64Temp0
   456  	}
   457  
   458  	if e-p == 0 {
   459  		return
   460  	}
   461  	rest := prng.Uint64MultiplyAdd()
   462  	if e-p >= 4 {
   463  		*(*uint32)((unsafe.Pointer)(p)) ^= uint32(rest)
   464  		rest >>= 32
   465  		p += 4
   466  	}
   467  	if e-p >= 2 {
   468  		*(*uint16)((unsafe.Pointer)(p)) ^= uint16(rest)
   469  		rest >>= 16
   470  		p += 2
   471  	}
   472  	if e-p >= 1 {
   473  		*(*uint8)((unsafe.Pointer)(p)) ^= uint8(rest)
   474  	}
   475  	return
   476  }
   477  
   478  // ReadUint64MultiplyAddWithReseed is an analog of math/rand.Read. This random
   479  // numbers could easily be predicted (it's not an analog of crypto/rand.Read).
   480  //
   481  // "Reseed" forces to use a new seed (generated using XORShift method) on setting value to
   482  // a pointer `& 0xff < 8`. Sometimes it allows to improve randomness of random numbers with a
   483  // small performance impact.
   484  // This method makes sense only if len(b) is large enough (>= 256 bytes).
   485  // Otherwise it could affect strongly performance or it will not improve the randomness.
   486  //
   487  // Applied PRNG method:
   488  // Uint64MultiplyAdd is a fast (but week) analog of `math/rand.Uint64`.
   489  //
   490  // See also: https://en.wikipedia.org/wiki/Linear_congruential_generator
   491  func (prng *PRNG) ReadUint64MultiplyAddWithReseed(b []byte) (l int, err error) {
   492  	l = len(b)
   493  	s := (uintptr)((unsafe.Pointer)(&b[0]))
   494  	p := s
   495  	e := s + uintptr(l)
   496  	{
   497  		state64Temp0 := prng.state64[0]
   498  		for f := e - 8; p <= f; p += 8 {
   499  			state64Temp0 *= primeNumber64bit0
   500  			state64Temp0 += primeNumber64bit1
   501  			*(*uint64)((unsafe.Pointer)(p)) = state64Temp0
   502  			if p&0xff < 8 {
   503  				continue
   504  			}
   505  			state64Temp0 = xorShift64(state64Temp0 ^ primeNumber64bit0)
   506  		}
   507  		prng.state64[0] = state64Temp0
   508  	}
   509  
   510  	if e-p == 0 {
   511  		return
   512  	}
   513  	rest := prng.Uint64MultiplyAdd()
   514  	if e-p >= 4 {
   515  		*(*uint32)((unsafe.Pointer)(p)) = uint32(rest)
   516  		rest >>= 32
   517  		p += 4
   518  	}
   519  	if e-p >= 2 {
   520  		*(*uint16)((unsafe.Pointer)(p)) = uint16(rest)
   521  		rest >>= 16
   522  		p += 2
   523  	}
   524  	if e-p >= 1 {
   525  		*(*uint8)((unsafe.Pointer)(p)) = uint8(rest)
   526  	}
   527  	return
   528  }
   529  
   530  // XORReadUint64MultiplyAddWithReseed XORs argument "b" with a pseudo-random value.
   531  // The result is the same (but faster) as:
   532  //
   533  // 	x := make([]byte, len(b))
   534  // 	mathrand.ReadUint64MultiplyAddWithReseed(x)
   535  // 	for i := range b {
   536  // 		b[i] ^= x[i]
   537  // 	}
   538  func (prng *PRNG) XORReadUint64MultiplyAddWithReseed(b []byte) (l int, err error) {
   539  	l = len(b)
   540  	s := (uintptr)((unsafe.Pointer)(&b[0]))
   541  	p := s
   542  	e := s + uintptr(l)
   543  	{
   544  		state64Temp0 := prng.state64[0]
   545  		for f := e - 8; p <= f; p += 8 {
   546  			state64Temp0 *= primeNumber64bit0
   547  			state64Temp0 += primeNumber64bit1
   548  			*(*uint64)((unsafe.Pointer)(p)) ^= state64Temp0
   549  			if p&0xff < 8 {
   550  				continue
   551  			}
   552  			state64Temp0 = xorShift64(state64Temp0 ^ primeNumber64bit0)
   553  		}
   554  		prng.state64[0] = state64Temp0
   555  	}
   556  
   557  	if e-p == 0 {
   558  		return
   559  	}
   560  	rest := prng.Uint64MultiplyAdd()
   561  	if e-p >= 4 {
   562  		*(*uint32)((unsafe.Pointer)(p)) ^= uint32(rest)
   563  		rest >>= 32
   564  		p += 4
   565  	}
   566  	if e-p >= 2 {
   567  		*(*uint16)((unsafe.Pointer)(p)) ^= uint16(rest)
   568  		rest >>= 16
   569  		p += 2
   570  	}
   571  	if e-p >= 1 {
   572  		*(*uint8)((unsafe.Pointer)(p)) ^= uint8(rest)
   573  	}
   574  	return
   575  }
   576  
   577  // ReadUint64AddRotate is an analog of math/rand.Read. This random
   578  // numbers could easily be predicted (it's not an analog of crypto/rand.Read).
   579  //
   580  // Applied PRNG method:
   581  // Uint64AddRotate is a very fast (but weak) analog of `math/rand.Uint64`.
   582  func (prng *PRNG) ReadUint64AddRotate(b []byte) (l int, err error) {
   583  	l = len(b)
   584  	s := (uintptr)((unsafe.Pointer)(&b[0]))
   585  	p := s
   586  	e := s + uintptr(l)
   587  	{
   588  		state64Temp0 := prng.state64[0]
   589  		for f := e - 8; p <= f; p += 8 {
   590  			state64Temp0 += primeNumber64bit1
   591  			state64Temp0 = rotateLeft64(state64Temp0, 32)
   592  			*(*uint64)((unsafe.Pointer)(p)) = state64Temp0
   593  		}
   594  		prng.state64[0] = state64Temp0
   595  	}
   596  
   597  	if e-p == 0 {
   598  		return
   599  	}
   600  	rest := prng.Uint64AddRotate()
   601  	if e-p >= 4 {
   602  		*(*uint32)((unsafe.Pointer)(p)) = uint32(rest)
   603  		rest >>= 32
   604  		p += 4
   605  	}
   606  	if e-p >= 2 {
   607  		*(*uint16)((unsafe.Pointer)(p)) = uint16(rest)
   608  		rest >>= 16
   609  		p += 2
   610  	}
   611  	if e-p >= 1 {
   612  		*(*uint8)((unsafe.Pointer)(p)) = uint8(rest)
   613  	}
   614  	return
   615  }
   616  
   617  // XORReadUint64AddRotate XORs argument "b" with a pseudo-random value.
   618  // The result is the same (but faster) as:
   619  //
   620  // 	x := make([]byte, len(b))
   621  // 	mathrand.ReadUint64AddRotate(x)
   622  // 	for i := range b {
   623  // 		b[i] ^= x[i]
   624  // 	}
   625  func (prng *PRNG) XORReadUint64AddRotate(b []byte) (l int, err error) {
   626  	l = len(b)
   627  	s := (uintptr)((unsafe.Pointer)(&b[0]))
   628  	p := s
   629  	e := s + uintptr(l)
   630  	{
   631  		state64Temp0 := prng.state64[0]
   632  		for f := e - 8; p <= f; p += 8 {
   633  			state64Temp0 += primeNumber64bit1
   634  			state64Temp0 = rotateLeft64(state64Temp0, 32)
   635  			*(*uint64)((unsafe.Pointer)(p)) ^= state64Temp0
   636  		}
   637  		prng.state64[0] = state64Temp0
   638  	}
   639  
   640  	if e-p == 0 {
   641  		return
   642  	}
   643  	rest := prng.Uint64AddRotate()
   644  	if e-p >= 4 {
   645  		*(*uint32)((unsafe.Pointer)(p)) ^= uint32(rest)
   646  		rest >>= 32
   647  		p += 4
   648  	}
   649  	if e-p >= 2 {
   650  		*(*uint16)((unsafe.Pointer)(p)) ^= uint16(rest)
   651  		rest >>= 16
   652  		p += 2
   653  	}
   654  	if e-p >= 1 {
   655  		*(*uint8)((unsafe.Pointer)(p)) ^= uint8(rest)
   656  	}
   657  	return
   658  }
   659  
   660  // ReadUint64AddRotateWithReseed is an analog of math/rand.Read. This random
   661  // numbers could easily be predicted (it's not an analog of crypto/rand.Read).
   662  //
   663  // "Reseed" forces to use a new seed (generated using XORShift method) on setting value to
   664  // a pointer `& 0xff < 8`. Sometimes it allows to improve randomness of random numbers with a
   665  // small performance impact.
   666  // This method makes sense only if len(b) is large enough (>= 256 bytes).
   667  // Otherwise it could affect strongly performance or it will not improve the randomness.
   668  //
   669  // Applied PRNG method:
   670  // Uint64AddRotate is a very fast (but weak) analog of `math/rand.Uint64`.
   671  func (prng *PRNG) ReadUint64AddRotateWithReseed(b []byte) (l int, err error) {
   672  	l = len(b)
   673  	s := (uintptr)((unsafe.Pointer)(&b[0]))
   674  	p := s
   675  	e := s + uintptr(l)
   676  	{
   677  		state64Temp0 := prng.state64[0]
   678  		for f := e - 8; p <= f; p += 8 {
   679  			state64Temp0 += primeNumber64bit1
   680  			state64Temp0 = rotateLeft64(state64Temp0, 32)
   681  			*(*uint64)((unsafe.Pointer)(p)) = state64Temp0
   682  			if p&0xff < 8 {
   683  				continue
   684  			}
   685  			state64Temp0 = xorShift64(state64Temp0 ^ primeNumber64bit0)
   686  		}
   687  		prng.state64[0] = state64Temp0
   688  	}
   689  
   690  	if e-p == 0 {
   691  		return
   692  	}
   693  	rest := prng.Uint64AddRotate()
   694  	if e-p >= 4 {
   695  		*(*uint32)((unsafe.Pointer)(p)) = uint32(rest)
   696  		rest >>= 32
   697  		p += 4
   698  	}
   699  	if e-p >= 2 {
   700  		*(*uint16)((unsafe.Pointer)(p)) = uint16(rest)
   701  		rest >>= 16
   702  		p += 2
   703  	}
   704  	if e-p >= 1 {
   705  		*(*uint8)((unsafe.Pointer)(p)) = uint8(rest)
   706  	}
   707  	return
   708  }
   709  
   710  // XORReadUint64AddRotateWithReseed XORs argument "b" with a pseudo-random value.
   711  // The result is the same (but faster) as:
   712  //
   713  // 	x := make([]byte, len(b))
   714  // 	mathrand.ReadUint64AddRotateWithReseed(x)
   715  // 	for i := range b {
   716  // 		b[i] ^= x[i]
   717  // 	}
   718  func (prng *PRNG) XORReadUint64AddRotateWithReseed(b []byte) (l int, err error) {
   719  	l = len(b)
   720  	s := (uintptr)((unsafe.Pointer)(&b[0]))
   721  	p := s
   722  	e := s + uintptr(l)
   723  	{
   724  		state64Temp0 := prng.state64[0]
   725  		for f := e - 8; p <= f; p += 8 {
   726  			state64Temp0 += primeNumber64bit1
   727  			state64Temp0 = rotateLeft64(state64Temp0, 32)
   728  			*(*uint64)((unsafe.Pointer)(p)) ^= state64Temp0
   729  			if p&0xff < 8 {
   730  				continue
   731  			}
   732  			state64Temp0 = xorShift64(state64Temp0 ^ primeNumber64bit0)
   733  		}
   734  		prng.state64[0] = state64Temp0
   735  	}
   736  
   737  	if e-p == 0 {
   738  		return
   739  	}
   740  	rest := prng.Uint64AddRotate()
   741  	if e-p >= 4 {
   742  		*(*uint32)((unsafe.Pointer)(p)) ^= uint32(rest)
   743  		rest >>= 32
   744  		p += 4
   745  	}
   746  	if e-p >= 2 {
   747  		*(*uint16)((unsafe.Pointer)(p)) ^= uint16(rest)
   748  		rest >>= 16
   749  		p += 2
   750  	}
   751  	if e-p >= 1 {
   752  		*(*uint8)((unsafe.Pointer)(p)) ^= uint8(rest)
   753  	}
   754  	return
   755  }
   756  
   757  // ReadUint64AddIfShiftXOR is an analog of math/rand.Read. This random
   758  // numbers could easily be predicted (it's not an analog of crypto/rand.Read).
   759  //
   760  // Applied PRNG method:
   761  // Uint64AddIfShiftXOR is a very fast (but weak) analog of `math/rand.Uint32`.
   762  func (prng *PRNG) ReadUint64AddIfShiftXOR(b []byte) (l int, err error) {
   763  	l = len(b)
   764  	s := (uintptr)((unsafe.Pointer)(&b[0]))
   765  	p := s
   766  	e := s + uintptr(l)
   767  	{
   768  		state64Temp0 := prng.state64[0]
   769  		for f := e - 8; p <= f; p += 8 {
   770  			state64Temp0 += primeNumber64bit1
   771  			if state64Temp0&0x02 == 0 {
   772  				state64Temp0 ^= state64Temp0 >> 32
   773  			}
   774  			*(*uint64)((unsafe.Pointer)(p)) = state64Temp0
   775  		}
   776  		prng.state64[0] = state64Temp0
   777  	}
   778  
   779  	if e-p == 0 {
   780  		return
   781  	}
   782  	rest := prng.Uint64AddIfShiftXOR()
   783  	if e-p >= 4 {
   784  		*(*uint32)((unsafe.Pointer)(p)) = uint32(rest)
   785  		rest >>= 32
   786  		p += 4
   787  	}
   788  	if e-p >= 2 {
   789  		*(*uint16)((unsafe.Pointer)(p)) = uint16(rest)
   790  		rest >>= 16
   791  		p += 2
   792  	}
   793  	if e-p >= 1 {
   794  		*(*uint8)((unsafe.Pointer)(p)) = uint8(rest)
   795  	}
   796  	return
   797  }
   798  
   799  // XORReadUint64AddIfShiftXOR XORs argument "b" with a pseudo-random value.
   800  // The result is the same (but faster) as:
   801  //
   802  // 	x := make([]byte, len(b))
   803  // 	mathrand.ReadUint64AddIfShiftXOR(x)
   804  // 	for i := range b {
   805  // 		b[i] ^= x[i]
   806  // 	}
   807  func (prng *PRNG) XORReadUint64AddIfShiftXOR(b []byte) (l int, err error) {
   808  	l = len(b)
   809  	s := (uintptr)((unsafe.Pointer)(&b[0]))
   810  	p := s
   811  	e := s + uintptr(l)
   812  	{
   813  		state64Temp0 := prng.state64[0]
   814  		for f := e - 8; p <= f; p += 8 {
   815  			state64Temp0 += primeNumber64bit1
   816  			if state64Temp0&0x02 == 0 {
   817  				state64Temp0 ^= state64Temp0 >> 32
   818  			}
   819  			*(*uint64)((unsafe.Pointer)(p)) ^= state64Temp0
   820  		}
   821  		prng.state64[0] = state64Temp0
   822  	}
   823  
   824  	if e-p == 0 {
   825  		return
   826  	}
   827  	rest := prng.Uint64AddIfShiftXOR()
   828  	if e-p >= 4 {
   829  		*(*uint32)((unsafe.Pointer)(p)) ^= uint32(rest)
   830  		rest >>= 32
   831  		p += 4
   832  	}
   833  	if e-p >= 2 {
   834  		*(*uint16)((unsafe.Pointer)(p)) ^= uint16(rest)
   835  		rest >>= 16
   836  		p += 2
   837  	}
   838  	if e-p >= 1 {
   839  		*(*uint8)((unsafe.Pointer)(p)) ^= uint8(rest)
   840  	}
   841  	return
   842  }
   843  
   844  // ReadUint64AddIfShiftXORWithReseed is an analog of math/rand.Read. This random
   845  // numbers could easily be predicted (it's not an analog of crypto/rand.Read).
   846  //
   847  // "Reseed" forces to use a new seed (generated using XORShift method) on setting value to
   848  // a pointer `& 0xff < 8`. Sometimes it allows to improve randomness of random numbers with a
   849  // small performance impact.
   850  // This method makes sense only if len(b) is large enough (>= 256 bytes).
   851  // Otherwise it could affect strongly performance or it will not improve the randomness.
   852  //
   853  // Applied PRNG method:
   854  // Uint64AddIfShiftXOR is a very fast (but weak) analog of `math/rand.Uint32`.
   855  func (prng *PRNG) ReadUint64AddIfShiftXORWithReseed(b []byte) (l int, err error) {
   856  	l = len(b)
   857  	s := (uintptr)((unsafe.Pointer)(&b[0]))
   858  	p := s
   859  	e := s + uintptr(l)
   860  	{
   861  		state64Temp0 := prng.state64[0]
   862  		for f := e - 8; p <= f; p += 8 {
   863  			state64Temp0 += primeNumber64bit1
   864  			if state64Temp0&0x02 == 0 {
   865  				state64Temp0 ^= state64Temp0 >> 32
   866  			}
   867  			*(*uint64)((unsafe.Pointer)(p)) = state64Temp0
   868  			if p&0xff < 8 {
   869  				continue
   870  			}
   871  			state64Temp0 = xorShift64(state64Temp0 ^ primeNumber64bit0)
   872  		}
   873  		prng.state64[0] = state64Temp0
   874  	}
   875  
   876  	if e-p == 0 {
   877  		return
   878  	}
   879  	rest := prng.Uint64AddIfShiftXOR()
   880  	if e-p >= 4 {
   881  		*(*uint32)((unsafe.Pointer)(p)) = uint32(rest)
   882  		rest >>= 32
   883  		p += 4
   884  	}
   885  	if e-p >= 2 {
   886  		*(*uint16)((unsafe.Pointer)(p)) = uint16(rest)
   887  		rest >>= 16
   888  		p += 2
   889  	}
   890  	if e-p >= 1 {
   891  		*(*uint8)((unsafe.Pointer)(p)) = uint8(rest)
   892  	}
   893  	return
   894  }
   895  
   896  // XORReadUint64AddIfShiftXORWithReseed XORs argument "b" with a pseudo-random value.
   897  // The result is the same (but faster) as:
   898  //
   899  // 	x := make([]byte, len(b))
   900  // 	mathrand.ReadUint64AddIfShiftXORWithReseed(x)
   901  // 	for i := range b {
   902  // 		b[i] ^= x[i]
   903  // 	}
   904  func (prng *PRNG) XORReadUint64AddIfShiftXORWithReseed(b []byte) (l int, err error) {
   905  	l = len(b)
   906  	s := (uintptr)((unsafe.Pointer)(&b[0]))
   907  	p := s
   908  	e := s + uintptr(l)
   909  	{
   910  		state64Temp0 := prng.state64[0]
   911  		for f := e - 8; p <= f; p += 8 {
   912  			state64Temp0 += primeNumber64bit1
   913  			if state64Temp0&0x02 == 0 {
   914  				state64Temp0 ^= state64Temp0 >> 32
   915  			}
   916  			*(*uint64)((unsafe.Pointer)(p)) ^= state64Temp0
   917  			if p&0xff < 8 {
   918  				continue
   919  			}
   920  			state64Temp0 = xorShift64(state64Temp0 ^ primeNumber64bit0)
   921  		}
   922  		prng.state64[0] = state64Temp0
   923  	}
   924  
   925  	if e-p == 0 {
   926  		return
   927  	}
   928  	rest := prng.Uint64AddIfShiftXOR()
   929  	if e-p >= 4 {
   930  		*(*uint32)((unsafe.Pointer)(p)) ^= uint32(rest)
   931  		rest >>= 32
   932  		p += 4
   933  	}
   934  	if e-p >= 2 {
   935  		*(*uint16)((unsafe.Pointer)(p)) ^= uint16(rest)
   936  		rest >>= 16
   937  		p += 2
   938  	}
   939  	if e-p >= 1 {
   940  		*(*uint8)((unsafe.Pointer)(p)) ^= uint8(rest)
   941  	}
   942  	return
   943  }
   944  
   945  // ReadUint64Xorshift is an analog of math/rand.Read. This random
   946  // numbers could easily be predicted (it's not an analog of crypto/rand.Read).
   947  //
   948  // Applied PRNG method:
   949  // Uint64Xorshift is a very fast (but weak) analog of `math/rand.Uint64`.
   950  //
   951  // See also: https://en.wikipedia.org/wiki/Xorshift
   952  func (prng *PRNG) ReadUint64Xorshift(b []byte) (l int, err error) {
   953  	l = len(b)
   954  	s := (uintptr)((unsafe.Pointer)(&b[0]))
   955  	p := s
   956  	e := s + uintptr(l)
   957  	{
   958  		state64Temp0 := prng.state64[0]
   959  		for f := e - 8; p <= f; p += 8 {
   960  			state64Temp0 ^= state64Temp0 << 13
   961  			state64Temp0 ^= state64Temp0 >> 7
   962  			state64Temp0 ^= state64Temp0 << 17
   963  			*(*uint64)((unsafe.Pointer)(p)) = state64Temp0
   964  		}
   965  		prng.state64[0] = state64Temp0
   966  	}
   967  
   968  	if e-p == 0 {
   969  		return
   970  	}
   971  	rest := prng.Uint64Xorshift()
   972  	if e-p >= 4 {
   973  		*(*uint32)((unsafe.Pointer)(p)) = uint32(rest)
   974  		rest >>= 32
   975  		p += 4
   976  	}
   977  	if e-p >= 2 {
   978  		*(*uint16)((unsafe.Pointer)(p)) = uint16(rest)
   979  		rest >>= 16
   980  		p += 2
   981  	}
   982  	if e-p >= 1 {
   983  		*(*uint8)((unsafe.Pointer)(p)) = uint8(rest)
   984  	}
   985  	return
   986  }
   987  
   988  // XORReadUint64Xorshift XORs argument "b" with a pseudo-random value.
   989  // The result is the same (but faster) as:
   990  //
   991  // 	x := make([]byte, len(b))
   992  // 	mathrand.ReadUint64Xorshift(x)
   993  // 	for i := range b {
   994  // 		b[i] ^= x[i]
   995  // 	}
   996  func (prng *PRNG) XORReadUint64Xorshift(b []byte) (l int, err error) {
   997  	l = len(b)
   998  	s := (uintptr)((unsafe.Pointer)(&b[0]))
   999  	p := s
  1000  	e := s + uintptr(l)
  1001  	{
  1002  		state64Temp0 := prng.state64[0]
  1003  		for f := e - 8; p <= f; p += 8 {
  1004  			state64Temp0 ^= state64Temp0 << 13
  1005  			state64Temp0 ^= state64Temp0 >> 7
  1006  			state64Temp0 ^= state64Temp0 << 17
  1007  			*(*uint64)((unsafe.Pointer)(p)) ^= state64Temp0
  1008  		}
  1009  		prng.state64[0] = state64Temp0
  1010  	}
  1011  
  1012  	if e-p == 0 {
  1013  		return
  1014  	}
  1015  	rest := prng.Uint64Xorshift()
  1016  	if e-p >= 4 {
  1017  		*(*uint32)((unsafe.Pointer)(p)) ^= uint32(rest)
  1018  		rest >>= 32
  1019  		p += 4
  1020  	}
  1021  	if e-p >= 2 {
  1022  		*(*uint16)((unsafe.Pointer)(p)) ^= uint16(rest)
  1023  		rest >>= 16
  1024  		p += 2
  1025  	}
  1026  	if e-p >= 1 {
  1027  		*(*uint8)((unsafe.Pointer)(p)) ^= uint8(rest)
  1028  	}
  1029  	return
  1030  }
  1031  
  1032  // ReadUint64XorshiftWithReseed is an analog of math/rand.Read. This random
  1033  // numbers could easily be predicted (it's not an analog of crypto/rand.Read).
  1034  //
  1035  // "Reseed" forces to use a new seed (generated using XORShift method) on setting value to
  1036  // a pointer `& 0xff < 8`. Sometimes it allows to improve randomness of random numbers with a
  1037  // small performance impact.
  1038  // This method makes sense only if len(b) is large enough (>= 256 bytes).
  1039  // Otherwise it could affect strongly performance or it will not improve the randomness.
  1040  //
  1041  // Applied PRNG method:
  1042  // Uint64Xorshift is a very fast (but weak) analog of `math/rand.Uint64`.
  1043  //
  1044  // See also: https://en.wikipedia.org/wiki/Xorshift
  1045  func (prng *PRNG) ReadUint64XorshiftWithReseed(b []byte) (l int, err error) {
  1046  	l = len(b)
  1047  	s := (uintptr)((unsafe.Pointer)(&b[0]))
  1048  	p := s
  1049  	e := s + uintptr(l)
  1050  	{
  1051  		state64Temp0 := prng.state64[0]
  1052  		for f := e - 8; p <= f; p += 8 {
  1053  			state64Temp0 ^= state64Temp0 << 13
  1054  			state64Temp0 ^= state64Temp0 >> 7
  1055  			state64Temp0 ^= state64Temp0 << 17
  1056  			*(*uint64)((unsafe.Pointer)(p)) = state64Temp0
  1057  			if p&0xff < 8 {
  1058  				continue
  1059  			}
  1060  			state64Temp0 = xorShift64(state64Temp0 ^ primeNumber64bit0)
  1061  		}
  1062  		prng.state64[0] = state64Temp0
  1063  	}
  1064  
  1065  	if e-p == 0 {
  1066  		return
  1067  	}
  1068  	rest := prng.Uint64Xorshift()
  1069  	if e-p >= 4 {
  1070  		*(*uint32)((unsafe.Pointer)(p)) = uint32(rest)
  1071  		rest >>= 32
  1072  		p += 4
  1073  	}
  1074  	if e-p >= 2 {
  1075  		*(*uint16)((unsafe.Pointer)(p)) = uint16(rest)
  1076  		rest >>= 16
  1077  		p += 2
  1078  	}
  1079  	if e-p >= 1 {
  1080  		*(*uint8)((unsafe.Pointer)(p)) = uint8(rest)
  1081  	}
  1082  	return
  1083  }
  1084  
  1085  // XORReadUint64XorshiftWithReseed XORs argument "b" with a pseudo-random value.
  1086  // The result is the same (but faster) as:
  1087  //
  1088  // 	x := make([]byte, len(b))
  1089  // 	mathrand.ReadUint64XorshiftWithReseed(x)
  1090  // 	for i := range b {
  1091  // 		b[i] ^= x[i]
  1092  // 	}
  1093  func (prng *PRNG) XORReadUint64XorshiftWithReseed(b []byte) (l int, err error) {
  1094  	l = len(b)
  1095  	s := (uintptr)((unsafe.Pointer)(&b[0]))
  1096  	p := s
  1097  	e := s + uintptr(l)
  1098  	{
  1099  		state64Temp0 := prng.state64[0]
  1100  		for f := e - 8; p <= f; p += 8 {
  1101  			state64Temp0 ^= state64Temp0 << 13
  1102  			state64Temp0 ^= state64Temp0 >> 7
  1103  			state64Temp0 ^= state64Temp0 << 17
  1104  			*(*uint64)((unsafe.Pointer)(p)) ^= state64Temp0
  1105  			if p&0xff < 8 {
  1106  				continue
  1107  			}
  1108  			state64Temp0 = xorShift64(state64Temp0 ^ primeNumber64bit0)
  1109  		}
  1110  		prng.state64[0] = state64Temp0
  1111  	}
  1112  
  1113  	if e-p == 0 {
  1114  		return
  1115  	}
  1116  	rest := prng.Uint64Xorshift()
  1117  	if e-p >= 4 {
  1118  		*(*uint32)((unsafe.Pointer)(p)) ^= uint32(rest)
  1119  		rest >>= 32
  1120  		p += 4
  1121  	}
  1122  	if e-p >= 2 {
  1123  		*(*uint16)((unsafe.Pointer)(p)) ^= uint16(rest)
  1124  		rest >>= 16
  1125  		p += 2
  1126  	}
  1127  	if e-p >= 1 {
  1128  		*(*uint8)((unsafe.Pointer)(p)) ^= uint8(rest)
  1129  	}
  1130  	return
  1131  }
  1132  
  1133  // ReadUint64Xoshiro256 is an analog of math/rand.Read. This random
  1134  // numbers could easily be predicted (it's not an analog of crypto/rand.Read).
  1135  //
  1136  // Applied PRNG method:
  1137  // See also: https://en.wikipedia.org/wiki/Xorshift#xoshiro_and_xoroshiro
  1138  func (prng *PRNG) ReadUint64Xoshiro256(b []byte) (l int, err error) {
  1139  	l = len(b)
  1140  	s := (uintptr)((unsafe.Pointer)(&b[0]))
  1141  	p := s
  1142  	e := s + uintptr(l)
  1143  	{
  1144  		var result uint64
  1145  		state64Temp1 := prng.state64[1]
  1146  		state64Temp2 := prng.state64[2]
  1147  		state64Temp0 := prng.state64[0]
  1148  		state64Temp3 := prng.state64[3]
  1149  		for f := e - 8; p <= f; p += 8 {
  1150  			result = rotateLeft64(state64Temp1*5, 7) * 9
  1151  			t := state64Temp1 << 17
  1152  			state64Temp2 ^= state64Temp0
  1153  			state64Temp3 ^= state64Temp1
  1154  			state64Temp1 ^= state64Temp2
  1155  			state64Temp0 ^= state64Temp3
  1156  			state64Temp2 ^= t
  1157  			state64Temp3 ^= rotateLeft64(state64Temp3, 45)
  1158  			*(*uint64)((unsafe.Pointer)(p)) = result
  1159  		}
  1160  		prng.state64[1] = state64Temp1
  1161  		prng.state64[2] = state64Temp2
  1162  		prng.state64[0] = state64Temp0
  1163  		prng.state64[3] = state64Temp3
  1164  	}
  1165  
  1166  	if e-p == 0 {
  1167  		return
  1168  	}
  1169  	rest := prng.Uint64Xoshiro256()
  1170  	if e-p >= 4 {
  1171  		*(*uint32)((unsafe.Pointer)(p)) = uint32(rest)
  1172  		rest >>= 32
  1173  		p += 4
  1174  	}
  1175  	if e-p >= 2 {
  1176  		*(*uint16)((unsafe.Pointer)(p)) = uint16(rest)
  1177  		rest >>= 16
  1178  		p += 2
  1179  	}
  1180  	if e-p >= 1 {
  1181  		*(*uint8)((unsafe.Pointer)(p)) = uint8(rest)
  1182  	}
  1183  	return
  1184  }
  1185  
  1186  // XORReadUint64Xoshiro256 XORs argument "b" with a pseudo-random value.
  1187  // The result is the same (but faster) as:
  1188  //
  1189  // 	x := make([]byte, len(b))
  1190  // 	mathrand.ReadUint64Xoshiro256(x)
  1191  // 	for i := range b {
  1192  // 		b[i] ^= x[i]
  1193  // 	}
  1194  func (prng *PRNG) XORReadUint64Xoshiro256(b []byte) (l int, err error) {
  1195  	l = len(b)
  1196  	s := (uintptr)((unsafe.Pointer)(&b[0]))
  1197  	p := s
  1198  	e := s + uintptr(l)
  1199  	{
  1200  		var result uint64
  1201  		state64Temp1 := prng.state64[1]
  1202  		state64Temp2 := prng.state64[2]
  1203  		state64Temp0 := prng.state64[0]
  1204  		state64Temp3 := prng.state64[3]
  1205  		for f := e - 8; p <= f; p += 8 {
  1206  			result = rotateLeft64(state64Temp1*5, 7) * 9
  1207  			t := state64Temp1 << 17
  1208  			state64Temp2 ^= state64Temp0
  1209  			state64Temp3 ^= state64Temp1
  1210  			state64Temp1 ^= state64Temp2
  1211  			state64Temp0 ^= state64Temp3
  1212  			state64Temp2 ^= t
  1213  			state64Temp3 ^= rotateLeft64(state64Temp3, 45)
  1214  			*(*uint64)((unsafe.Pointer)(p)) ^= result
  1215  		}
  1216  		prng.state64[1] = state64Temp1
  1217  		prng.state64[2] = state64Temp2
  1218  		prng.state64[0] = state64Temp0
  1219  		prng.state64[3] = state64Temp3
  1220  	}
  1221  
  1222  	if e-p == 0 {
  1223  		return
  1224  	}
  1225  	rest := prng.Uint64Xoshiro256()
  1226  	if e-p >= 4 {
  1227  		*(*uint32)((unsafe.Pointer)(p)) ^= uint32(rest)
  1228  		rest >>= 32
  1229  		p += 4
  1230  	}
  1231  	if e-p >= 2 {
  1232  		*(*uint16)((unsafe.Pointer)(p)) ^= uint16(rest)
  1233  		rest >>= 16
  1234  		p += 2
  1235  	}
  1236  	if e-p >= 1 {
  1237  		*(*uint8)((unsafe.Pointer)(p)) ^= uint8(rest)
  1238  	}
  1239  	return
  1240  }
  1241  
  1242  // ReadUint64Xoshiro256WithReseed is an analog of math/rand.Read. This random
  1243  // numbers could easily be predicted (it's not an analog of crypto/rand.Read).
  1244  //
  1245  // "Reseed" forces to use a new seed (generated using XORShift method) on setting value to
  1246  // a pointer `& 0xff < 8`. Sometimes it allows to improve randomness of random numbers with a
  1247  // small performance impact.
  1248  // This method makes sense only if len(b) is large enough (>= 256 bytes).
  1249  // Otherwise it could affect strongly performance or it will not improve the randomness.
  1250  //
  1251  // Applied PRNG method:
  1252  // See also: https://en.wikipedia.org/wiki/Xorshift#xoshiro_and_xoroshiro
  1253  func (prng *PRNG) ReadUint64Xoshiro256WithReseed(b []byte) (l int, err error) {
  1254  	l = len(b)
  1255  	s := (uintptr)((unsafe.Pointer)(&b[0]))
  1256  	p := s
  1257  	e := s + uintptr(l)
  1258  	{
  1259  		var result uint64
  1260  		state64Temp1 := prng.state64[1]
  1261  		state64Temp2 := prng.state64[2]
  1262  		state64Temp0 := prng.state64[0]
  1263  		state64Temp3 := prng.state64[3]
  1264  		for f := e - 8; p <= f; p += 8 {
  1265  			result = rotateLeft64(state64Temp1*5, 7) * 9
  1266  			t := state64Temp1 << 17
  1267  			state64Temp2 ^= state64Temp0
  1268  			state64Temp3 ^= state64Temp1
  1269  			state64Temp1 ^= state64Temp2
  1270  			state64Temp0 ^= state64Temp3
  1271  			state64Temp2 ^= t
  1272  			state64Temp3 ^= rotateLeft64(state64Temp3, 45)
  1273  			*(*uint64)((unsafe.Pointer)(p)) = result
  1274  			if p&0xff < 8 {
  1275  				continue
  1276  			}
  1277  			state64Temp0 = xorShift64(state64Temp0 ^ primeNumber64bit0)
  1278  		}
  1279  		prng.state64[1] = state64Temp1
  1280  		prng.state64[2] = state64Temp2
  1281  		prng.state64[0] = state64Temp0
  1282  		prng.state64[3] = state64Temp3
  1283  	}
  1284  
  1285  	if e-p == 0 {
  1286  		return
  1287  	}
  1288  	rest := prng.Uint64Xoshiro256()
  1289  	if e-p >= 4 {
  1290  		*(*uint32)((unsafe.Pointer)(p)) = uint32(rest)
  1291  		rest >>= 32
  1292  		p += 4
  1293  	}
  1294  	if e-p >= 2 {
  1295  		*(*uint16)((unsafe.Pointer)(p)) = uint16(rest)
  1296  		rest >>= 16
  1297  		p += 2
  1298  	}
  1299  	if e-p >= 1 {
  1300  		*(*uint8)((unsafe.Pointer)(p)) = uint8(rest)
  1301  	}
  1302  	return
  1303  }
  1304  
  1305  // XORReadUint64Xoshiro256WithReseed XORs argument "b" with a pseudo-random value.
  1306  // The result is the same (but faster) as:
  1307  //
  1308  // 	x := make([]byte, len(b))
  1309  // 	mathrand.ReadUint64Xoshiro256WithReseed(x)
  1310  // 	for i := range b {
  1311  // 		b[i] ^= x[i]
  1312  // 	}
  1313  func (prng *PRNG) XORReadUint64Xoshiro256WithReseed(b []byte) (l int, err error) {
  1314  	l = len(b)
  1315  	s := (uintptr)((unsafe.Pointer)(&b[0]))
  1316  	p := s
  1317  	e := s + uintptr(l)
  1318  	{
  1319  		var result uint64
  1320  		state64Temp1 := prng.state64[1]
  1321  		state64Temp2 := prng.state64[2]
  1322  		state64Temp0 := prng.state64[0]
  1323  		state64Temp3 := prng.state64[3]
  1324  		for f := e - 8; p <= f; p += 8 {
  1325  			result = rotateLeft64(state64Temp1*5, 7) * 9
  1326  			t := state64Temp1 << 17
  1327  			state64Temp2 ^= state64Temp0
  1328  			state64Temp3 ^= state64Temp1
  1329  			state64Temp1 ^= state64Temp2
  1330  			state64Temp0 ^= state64Temp3
  1331  			state64Temp2 ^= t
  1332  			state64Temp3 ^= rotateLeft64(state64Temp3, 45)
  1333  			*(*uint64)((unsafe.Pointer)(p)) ^= result
  1334  			if p&0xff < 8 {
  1335  				continue
  1336  			}
  1337  			state64Temp0 = xorShift64(state64Temp0 ^ primeNumber64bit0)
  1338  		}
  1339  		prng.state64[1] = state64Temp1
  1340  		prng.state64[2] = state64Temp2
  1341  		prng.state64[0] = state64Temp0
  1342  		prng.state64[3] = state64Temp3
  1343  	}
  1344  
  1345  	if e-p == 0 {
  1346  		return
  1347  	}
  1348  	rest := prng.Uint64Xoshiro256()
  1349  	if e-p >= 4 {
  1350  		*(*uint32)((unsafe.Pointer)(p)) ^= uint32(rest)
  1351  		rest >>= 32
  1352  		p += 4
  1353  	}
  1354  	if e-p >= 2 {
  1355  		*(*uint16)((unsafe.Pointer)(p)) ^= uint16(rest)
  1356  		rest >>= 16
  1357  		p += 2
  1358  	}
  1359  	if e-p >= 1 {
  1360  		*(*uint8)((unsafe.Pointer)(p)) ^= uint8(rest)
  1361  	}
  1362  	return
  1363  }
  1364  
  1365  // ReadUint64MSWS is an analog of math/rand.Read. This random
  1366  // numbers could easily be predicted (it's not an analog of crypto/rand.Read).
  1367  //
  1368  // Applied PRNG method:
  1369  // See also: https://en.wikipedia.org/wiki/Middle-square_method
  1370  func (prng *PRNG) ReadUint64MSWS(b []byte) (l int, err error) {
  1371  	l = len(b)
  1372  	s := (uintptr)((unsafe.Pointer)(&b[0]))
  1373  	p := s
  1374  	e := s + uintptr(l)
  1375  	{
  1376  		state64Temp0 := prng.state64[0]
  1377  		state64Temp1 := prng.state64[1]
  1378  		for f := e - 8; p <= f; p += 8 {
  1379  			state64Temp0 *= state64Temp0
  1380  			state64Temp1 += mswsSeed
  1381  			state64Temp0 += state64Temp1
  1382  			state64Temp0 = rotateLeft64(state64Temp0, 32)
  1383  			*(*uint64)((unsafe.Pointer)(p)) = state64Temp0
  1384  		}
  1385  		prng.state64[0] = state64Temp0
  1386  		prng.state64[1] = state64Temp1
  1387  	}
  1388  
  1389  	if e-p == 0 {
  1390  		return
  1391  	}
  1392  	rest := prng.Uint64MSWS()
  1393  	if e-p >= 4 {
  1394  		*(*uint32)((unsafe.Pointer)(p)) = uint32(rest)
  1395  		rest >>= 32
  1396  		p += 4
  1397  	}
  1398  	if e-p >= 2 {
  1399  		*(*uint16)((unsafe.Pointer)(p)) = uint16(rest)
  1400  		rest >>= 16
  1401  		p += 2
  1402  	}
  1403  	if e-p >= 1 {
  1404  		*(*uint8)((unsafe.Pointer)(p)) = uint8(rest)
  1405  	}
  1406  	return
  1407  }
  1408  
  1409  // XORReadUint64MSWS XORs argument "b" with a pseudo-random value.
  1410  // The result is the same (but faster) as:
  1411  //
  1412  // 	x := make([]byte, len(b))
  1413  // 	mathrand.ReadUint64MSWS(x)
  1414  // 	for i := range b {
  1415  // 		b[i] ^= x[i]
  1416  // 	}
  1417  func (prng *PRNG) XORReadUint64MSWS(b []byte) (l int, err error) {
  1418  	l = len(b)
  1419  	s := (uintptr)((unsafe.Pointer)(&b[0]))
  1420  	p := s
  1421  	e := s + uintptr(l)
  1422  	{
  1423  		state64Temp0 := prng.state64[0]
  1424  		state64Temp1 := prng.state64[1]
  1425  		for f := e - 8; p <= f; p += 8 {
  1426  			state64Temp0 *= state64Temp0
  1427  			state64Temp1 += mswsSeed
  1428  			state64Temp0 += state64Temp1
  1429  			state64Temp0 = rotateLeft64(state64Temp0, 32)
  1430  			*(*uint64)((unsafe.Pointer)(p)) ^= state64Temp0
  1431  		}
  1432  		prng.state64[0] = state64Temp0
  1433  		prng.state64[1] = state64Temp1
  1434  	}
  1435  
  1436  	if e-p == 0 {
  1437  		return
  1438  	}
  1439  	rest := prng.Uint64MSWS()
  1440  	if e-p >= 4 {
  1441  		*(*uint32)((unsafe.Pointer)(p)) ^= uint32(rest)
  1442  		rest >>= 32
  1443  		p += 4
  1444  	}
  1445  	if e-p >= 2 {
  1446  		*(*uint16)((unsafe.Pointer)(p)) ^= uint16(rest)
  1447  		rest >>= 16
  1448  		p += 2
  1449  	}
  1450  	if e-p >= 1 {
  1451  		*(*uint8)((unsafe.Pointer)(p)) ^= uint8(rest)
  1452  	}
  1453  	return
  1454  }
  1455  
  1456  // ReadUint64MSWSWithReseed is an analog of math/rand.Read. This random
  1457  // numbers could easily be predicted (it's not an analog of crypto/rand.Read).
  1458  //
  1459  // "Reseed" forces to use a new seed (generated using XORShift method) on setting value to
  1460  // a pointer `& 0xff < 8`. Sometimes it allows to improve randomness of random numbers with a
  1461  // small performance impact.
  1462  // This method makes sense only if len(b) is large enough (>= 256 bytes).
  1463  // Otherwise it could affect strongly performance or it will not improve the randomness.
  1464  //
  1465  // Applied PRNG method:
  1466  // See also: https://en.wikipedia.org/wiki/Middle-square_method
  1467  func (prng *PRNG) ReadUint64MSWSWithReseed(b []byte) (l int, err error) {
  1468  	l = len(b)
  1469  	s := (uintptr)((unsafe.Pointer)(&b[0]))
  1470  	p := s
  1471  	e := s + uintptr(l)
  1472  	{
  1473  		state64Temp0 := prng.state64[0]
  1474  		state64Temp1 := prng.state64[1]
  1475  		for f := e - 8; p <= f; p += 8 {
  1476  			state64Temp0 *= state64Temp0
  1477  			state64Temp1 += mswsSeed
  1478  			state64Temp0 += state64Temp1
  1479  			state64Temp0 = rotateLeft64(state64Temp0, 32)
  1480  			*(*uint64)((unsafe.Pointer)(p)) = state64Temp0
  1481  			if p&0xff < 8 {
  1482  				continue
  1483  			}
  1484  			state64Temp0 = xorShift64(state64Temp0 ^ primeNumber64bit0)
  1485  		}
  1486  		prng.state64[0] = state64Temp0
  1487  		prng.state64[1] = state64Temp1
  1488  	}
  1489  
  1490  	if e-p == 0 {
  1491  		return
  1492  	}
  1493  	rest := prng.Uint64MSWS()
  1494  	if e-p >= 4 {
  1495  		*(*uint32)((unsafe.Pointer)(p)) = uint32(rest)
  1496  		rest >>= 32
  1497  		p += 4
  1498  	}
  1499  	if e-p >= 2 {
  1500  		*(*uint16)((unsafe.Pointer)(p)) = uint16(rest)
  1501  		rest >>= 16
  1502  		p += 2
  1503  	}
  1504  	if e-p >= 1 {
  1505  		*(*uint8)((unsafe.Pointer)(p)) = uint8(rest)
  1506  	}
  1507  	return
  1508  }
  1509  
  1510  // XORReadUint64MSWSWithReseed XORs argument "b" with a pseudo-random value.
  1511  // The result is the same (but faster) as:
  1512  //
  1513  // 	x := make([]byte, len(b))
  1514  // 	mathrand.ReadUint64MSWSWithReseed(x)
  1515  // 	for i := range b {
  1516  // 		b[i] ^= x[i]
  1517  // 	}
  1518  func (prng *PRNG) XORReadUint64MSWSWithReseed(b []byte) (l int, err error) {
  1519  	l = len(b)
  1520  	s := (uintptr)((unsafe.Pointer)(&b[0]))
  1521  	p := s
  1522  	e := s + uintptr(l)
  1523  	{
  1524  		state64Temp0 := prng.state64[0]
  1525  		state64Temp1 := prng.state64[1]
  1526  		for f := e - 8; p <= f; p += 8 {
  1527  			state64Temp0 *= state64Temp0
  1528  			state64Temp1 += mswsSeed
  1529  			state64Temp0 += state64Temp1
  1530  			state64Temp0 = rotateLeft64(state64Temp0, 32)
  1531  			*(*uint64)((unsafe.Pointer)(p)) ^= state64Temp0
  1532  			if p&0xff < 8 {
  1533  				continue
  1534  			}
  1535  			state64Temp0 = xorShift64(state64Temp0 ^ primeNumber64bit0)
  1536  		}
  1537  		prng.state64[0] = state64Temp0
  1538  		prng.state64[1] = state64Temp1
  1539  	}
  1540  
  1541  	if e-p == 0 {
  1542  		return
  1543  	}
  1544  	rest := prng.Uint64MSWS()
  1545  	if e-p >= 4 {
  1546  		*(*uint32)((unsafe.Pointer)(p)) ^= uint32(rest)
  1547  		rest >>= 32
  1548  		p += 4
  1549  	}
  1550  	if e-p >= 2 {
  1551  		*(*uint16)((unsafe.Pointer)(p)) ^= uint16(rest)
  1552  		rest >>= 16
  1553  		p += 2
  1554  	}
  1555  	if e-p >= 1 {
  1556  		*(*uint8)((unsafe.Pointer)(p)) ^= uint8(rest)
  1557  	}
  1558  	return
  1559  }
  1560  
  1561  // ReadUint32AddRotateMultiply is an analog of math/rand.Read. This random
  1562  // numbers could easily be predicted (it's not an analog of crypto/rand.Read).
  1563  //
  1564  // Applied PRNG method:
  1565  // Uint32AddRotateMultiply is a fast analog of `math/rand.Uint32`.
  1566  //
  1567  // The reliability on statistical tests of this method is unknown. This is
  1568  // improved LCG method, so see also Uint32MultiplyAdd.
  1569  func (prng *PRNG) ReadUint32AddRotateMultiply(b []byte) (l int, err error) {
  1570  	l = len(b)
  1571  	s := (uintptr)((unsafe.Pointer)(&b[0]))
  1572  	p := s
  1573  	e := s + uintptr(l)
  1574  	{
  1575  		state32Temp0 := prng.state32[0]
  1576  		for f := e - 4; p <= f; p += 4 {
  1577  			state32Temp0 += primeNumber32bit1
  1578  			state32Temp0 = rotateLeft32(state32Temp0, 32)
  1579  			state32Temp0 *= primeNumber32bit0
  1580  			*(*uint32)((unsafe.Pointer)(p)) = state32Temp0
  1581  		}
  1582  		prng.state32[0] = state32Temp0
  1583  	}
  1584  
  1585  	if e-p == 0 {
  1586  		return
  1587  	}
  1588  	rest := prng.Uint32AddRotateMultiply()
  1589  	if e-p >= 2 {
  1590  		*(*uint16)((unsafe.Pointer)(p)) = uint16(rest)
  1591  		rest >>= 16
  1592  		p += 2
  1593  	}
  1594  	if e-p >= 1 {
  1595  		*(*uint8)((unsafe.Pointer)(p)) = uint8(rest)
  1596  	}
  1597  	return
  1598  }
  1599  
  1600  // XORReadUint32AddRotateMultiply XORs argument "b" with a pseudo-random value.
  1601  // The result is the same (but faster) as:
  1602  //
  1603  // 	x := make([]byte, len(b))
  1604  // 	mathrand.ReadUint32AddRotateMultiply(x)
  1605  // 	for i := range b {
  1606  // 		b[i] ^= x[i]
  1607  // 	}
  1608  func (prng *PRNG) XORReadUint32AddRotateMultiply(b []byte) (l int, err error) {
  1609  	l = len(b)
  1610  	s := (uintptr)((unsafe.Pointer)(&b[0]))
  1611  	p := s
  1612  	e := s + uintptr(l)
  1613  	{
  1614  		state32Temp0 := prng.state32[0]
  1615  		for f := e - 4; p <= f; p += 4 {
  1616  			state32Temp0 += primeNumber32bit1
  1617  			state32Temp0 = rotateLeft32(state32Temp0, 32)
  1618  			state32Temp0 *= primeNumber32bit0
  1619  			*(*uint32)((unsafe.Pointer)(p)) ^= state32Temp0
  1620  		}
  1621  		prng.state32[0] = state32Temp0
  1622  	}
  1623  
  1624  	if e-p == 0 {
  1625  		return
  1626  	}
  1627  	rest := prng.Uint32AddRotateMultiply()
  1628  	if e-p >= 2 {
  1629  		*(*uint16)((unsafe.Pointer)(p)) ^= uint16(rest)
  1630  		rest >>= 16
  1631  		p += 2
  1632  	}
  1633  	if e-p >= 1 {
  1634  		*(*uint8)((unsafe.Pointer)(p)) ^= uint8(rest)
  1635  	}
  1636  	return
  1637  }
  1638  
  1639  // ReadUint32AddRotateMultiplyWithReseed is an analog of math/rand.Read. This random
  1640  // numbers could easily be predicted (it's not an analog of crypto/rand.Read).
  1641  //
  1642  // "Reseed" forces to use a new seed (generated using XORShift method) on setting value to
  1643  // a pointer `& 0xff < 4`. Sometimes it allows to improve randomness of random numbers with a
  1644  // small performance impact.
  1645  // This method makes sense only if len(b) is large enough (>= 256 bytes).
  1646  // Otherwise it could affect strongly performance or it will not improve the randomness.
  1647  //
  1648  // Applied PRNG method:
  1649  // Uint32AddRotateMultiply is a fast analog of `math/rand.Uint32`.
  1650  //
  1651  // The reliability on statistical tests of this method is unknown. This is
  1652  // improved LCG method, so see also Uint32MultiplyAdd.
  1653  func (prng *PRNG) ReadUint32AddRotateMultiplyWithReseed(b []byte) (l int, err error) {
  1654  	l = len(b)
  1655  	s := (uintptr)((unsafe.Pointer)(&b[0]))
  1656  	p := s
  1657  	e := s + uintptr(l)
  1658  	{
  1659  		state32Temp0 := prng.state32[0]
  1660  		for f := e - 4; p <= f; p += 4 {
  1661  			state32Temp0 += primeNumber32bit1
  1662  			state32Temp0 = rotateLeft32(state32Temp0, 32)
  1663  			state32Temp0 *= primeNumber32bit0
  1664  			*(*uint32)((unsafe.Pointer)(p)) = state32Temp0
  1665  			if p&0xff < 4 {
  1666  				continue
  1667  			}
  1668  			state32Temp0 = (uint32)(xorShift32(state32Temp0 ^ primeNumber32bit0))
  1669  		}
  1670  		prng.state32[0] = state32Temp0
  1671  	}
  1672  
  1673  	if e-p == 0 {
  1674  		return
  1675  	}
  1676  	rest := prng.Uint32AddRotateMultiply()
  1677  	if e-p >= 2 {
  1678  		*(*uint16)((unsafe.Pointer)(p)) = uint16(rest)
  1679  		rest >>= 16
  1680  		p += 2
  1681  	}
  1682  	if e-p >= 1 {
  1683  		*(*uint8)((unsafe.Pointer)(p)) = uint8(rest)
  1684  	}
  1685  	return
  1686  }
  1687  
  1688  // XORReadUint32AddRotateMultiplyWithReseed XORs argument "b" with a pseudo-random value.
  1689  // The result is the same (but faster) as:
  1690  //
  1691  // 	x := make([]byte, len(b))
  1692  // 	mathrand.ReadUint32AddRotateMultiplyWithReseed(x)
  1693  // 	for i := range b {
  1694  // 		b[i] ^= x[i]
  1695  // 	}
  1696  func (prng *PRNG) XORReadUint32AddRotateMultiplyWithReseed(b []byte) (l int, err error) {
  1697  	l = len(b)
  1698  	s := (uintptr)((unsafe.Pointer)(&b[0]))
  1699  	p := s
  1700  	e := s + uintptr(l)
  1701  	{
  1702  		state32Temp0 := prng.state32[0]
  1703  		for f := e - 4; p <= f; p += 4 {
  1704  			state32Temp0 += primeNumber32bit1
  1705  			state32Temp0 = rotateLeft32(state32Temp0, 32)
  1706  			state32Temp0 *= primeNumber32bit0
  1707  			*(*uint32)((unsafe.Pointer)(p)) ^= state32Temp0
  1708  			if p&0xff < 4 {
  1709  				continue
  1710  			}
  1711  			state32Temp0 = (uint32)(xorShift32(state32Temp0 ^ primeNumber32bit0))
  1712  		}
  1713  		prng.state32[0] = state32Temp0
  1714  	}
  1715  
  1716  	if e-p == 0 {
  1717  		return
  1718  	}
  1719  	rest := prng.Uint32AddRotateMultiply()
  1720  	if e-p >= 2 {
  1721  		*(*uint16)((unsafe.Pointer)(p)) ^= uint16(rest)
  1722  		rest >>= 16
  1723  		p += 2
  1724  	}
  1725  	if e-p >= 1 {
  1726  		*(*uint8)((unsafe.Pointer)(p)) ^= uint8(rest)
  1727  	}
  1728  	return
  1729  }
  1730  
  1731  // ReadUint32MultiplyAdd is an analog of math/rand.Read. This random
  1732  // numbers could easily be predicted (it's not an analog of crypto/rand.Read).
  1733  //
  1734  // Applied PRNG method:
  1735  // Uint32MultiplyAdd is a fast (but week) analog of `math/rand.Uint32`.
  1736  //
  1737  // See also: https://en.wikipedia.org/wiki/Linear_congruential_generator
  1738  func (prng *PRNG) ReadUint32MultiplyAdd(b []byte) (l int, err error) {
  1739  	l = len(b)
  1740  	s := (uintptr)((unsafe.Pointer)(&b[0]))
  1741  	p := s
  1742  	e := s + uintptr(l)
  1743  	{
  1744  		state32Temp0 := prng.state32[0]
  1745  		for f := e - 4; p <= f; p += 4 {
  1746  			state32Temp0 *= primeNumber32bit0
  1747  			state32Temp0 += primeNumber32bit1
  1748  			*(*uint32)((unsafe.Pointer)(p)) = state32Temp0
  1749  		}
  1750  		prng.state32[0] = state32Temp0
  1751  	}
  1752  
  1753  	if e-p == 0 {
  1754  		return
  1755  	}
  1756  	rest := prng.Uint32MultiplyAdd()
  1757  	if e-p >= 2 {
  1758  		*(*uint16)((unsafe.Pointer)(p)) = uint16(rest)
  1759  		rest >>= 16
  1760  		p += 2
  1761  	}
  1762  	if e-p >= 1 {
  1763  		*(*uint8)((unsafe.Pointer)(p)) = uint8(rest)
  1764  	}
  1765  	return
  1766  }
  1767  
  1768  // XORReadUint32MultiplyAdd XORs argument "b" with a pseudo-random value.
  1769  // The result is the same (but faster) as:
  1770  //
  1771  // 	x := make([]byte, len(b))
  1772  // 	mathrand.ReadUint32MultiplyAdd(x)
  1773  // 	for i := range b {
  1774  // 		b[i] ^= x[i]
  1775  // 	}
  1776  func (prng *PRNG) XORReadUint32MultiplyAdd(b []byte) (l int, err error) {
  1777  	l = len(b)
  1778  	s := (uintptr)((unsafe.Pointer)(&b[0]))
  1779  	p := s
  1780  	e := s + uintptr(l)
  1781  	{
  1782  		state32Temp0 := prng.state32[0]
  1783  		for f := e - 4; p <= f; p += 4 {
  1784  			state32Temp0 *= primeNumber32bit0
  1785  			state32Temp0 += primeNumber32bit1
  1786  			*(*uint32)((unsafe.Pointer)(p)) ^= state32Temp0
  1787  		}
  1788  		prng.state32[0] = state32Temp0
  1789  	}
  1790  
  1791  	if e-p == 0 {
  1792  		return
  1793  	}
  1794  	rest := prng.Uint32MultiplyAdd()
  1795  	if e-p >= 2 {
  1796  		*(*uint16)((unsafe.Pointer)(p)) ^= uint16(rest)
  1797  		rest >>= 16
  1798  		p += 2
  1799  	}
  1800  	if e-p >= 1 {
  1801  		*(*uint8)((unsafe.Pointer)(p)) ^= uint8(rest)
  1802  	}
  1803  	return
  1804  }
  1805  
  1806  // ReadUint32MultiplyAddWithReseed is an analog of math/rand.Read. This random
  1807  // numbers could easily be predicted (it's not an analog of crypto/rand.Read).
  1808  //
  1809  // "Reseed" forces to use a new seed (generated using XORShift method) on setting value to
  1810  // a pointer `& 0xff < 4`. Sometimes it allows to improve randomness of random numbers with a
  1811  // small performance impact.
  1812  // This method makes sense only if len(b) is large enough (>= 256 bytes).
  1813  // Otherwise it could affect strongly performance or it will not improve the randomness.
  1814  //
  1815  // Applied PRNG method:
  1816  // Uint32MultiplyAdd is a fast (but week) analog of `math/rand.Uint32`.
  1817  //
  1818  // See also: https://en.wikipedia.org/wiki/Linear_congruential_generator
  1819  func (prng *PRNG) ReadUint32MultiplyAddWithReseed(b []byte) (l int, err error) {
  1820  	l = len(b)
  1821  	s := (uintptr)((unsafe.Pointer)(&b[0]))
  1822  	p := s
  1823  	e := s + uintptr(l)
  1824  	{
  1825  		state32Temp0 := prng.state32[0]
  1826  		for f := e - 4; p <= f; p += 4 {
  1827  			state32Temp0 *= primeNumber32bit0
  1828  			state32Temp0 += primeNumber32bit1
  1829  			*(*uint32)((unsafe.Pointer)(p)) = state32Temp0
  1830  			if p&0xff < 4 {
  1831  				continue
  1832  			}
  1833  			state32Temp0 = (uint32)(xorShift32(state32Temp0 ^ primeNumber32bit0))
  1834  		}
  1835  		prng.state32[0] = state32Temp0
  1836  	}
  1837  
  1838  	if e-p == 0 {
  1839  		return
  1840  	}
  1841  	rest := prng.Uint32MultiplyAdd()
  1842  	if e-p >= 2 {
  1843  		*(*uint16)((unsafe.Pointer)(p)) = uint16(rest)
  1844  		rest >>= 16
  1845  		p += 2
  1846  	}
  1847  	if e-p >= 1 {
  1848  		*(*uint8)((unsafe.Pointer)(p)) = uint8(rest)
  1849  	}
  1850  	return
  1851  }
  1852  
  1853  // XORReadUint32MultiplyAddWithReseed XORs argument "b" with a pseudo-random value.
  1854  // The result is the same (but faster) as:
  1855  //
  1856  // 	x := make([]byte, len(b))
  1857  // 	mathrand.ReadUint32MultiplyAddWithReseed(x)
  1858  // 	for i := range b {
  1859  // 		b[i] ^= x[i]
  1860  // 	}
  1861  func (prng *PRNG) XORReadUint32MultiplyAddWithReseed(b []byte) (l int, err error) {
  1862  	l = len(b)
  1863  	s := (uintptr)((unsafe.Pointer)(&b[0]))
  1864  	p := s
  1865  	e := s + uintptr(l)
  1866  	{
  1867  		state32Temp0 := prng.state32[0]
  1868  		for f := e - 4; p <= f; p += 4 {
  1869  			state32Temp0 *= primeNumber32bit0
  1870  			state32Temp0 += primeNumber32bit1
  1871  			*(*uint32)((unsafe.Pointer)(p)) ^= state32Temp0
  1872  			if p&0xff < 4 {
  1873  				continue
  1874  			}
  1875  			state32Temp0 = (uint32)(xorShift32(state32Temp0 ^ primeNumber32bit0))
  1876  		}
  1877  		prng.state32[0] = state32Temp0
  1878  	}
  1879  
  1880  	if e-p == 0 {
  1881  		return
  1882  	}
  1883  	rest := prng.Uint32MultiplyAdd()
  1884  	if e-p >= 2 {
  1885  		*(*uint16)((unsafe.Pointer)(p)) ^= uint16(rest)
  1886  		rest >>= 16
  1887  		p += 2
  1888  	}
  1889  	if e-p >= 1 {
  1890  		*(*uint8)((unsafe.Pointer)(p)) ^= uint8(rest)
  1891  	}
  1892  	return
  1893  }
  1894  
  1895  // ReadUint32AddRotate is an analog of math/rand.Read. This random
  1896  // numbers could easily be predicted (it's not an analog of crypto/rand.Read).
  1897  //
  1898  // Applied PRNG method:
  1899  // Uint32AddRotate is a very fast (but weak) analog of `math/rand.Uint32`.
  1900  func (prng *PRNG) ReadUint32AddRotate(b []byte) (l int, err error) {
  1901  	l = len(b)
  1902  	s := (uintptr)((unsafe.Pointer)(&b[0]))
  1903  	p := s
  1904  	e := s + uintptr(l)
  1905  	{
  1906  		state32Temp0 := prng.state32[0]
  1907  		for f := e - 4; p <= f; p += 4 {
  1908  			state32Temp0 += primeNumber32bit0
  1909  			state32Temp0 = rotateLeft32(state32Temp0, 32)
  1910  			*(*uint32)((unsafe.Pointer)(p)) = state32Temp0
  1911  		}
  1912  		prng.state32[0] = state32Temp0
  1913  	}
  1914  
  1915  	if e-p == 0 {
  1916  		return
  1917  	}
  1918  	rest := prng.Uint32AddRotate()
  1919  	if e-p >= 2 {
  1920  		*(*uint16)((unsafe.Pointer)(p)) = uint16(rest)
  1921  		rest >>= 16
  1922  		p += 2
  1923  	}
  1924  	if e-p >= 1 {
  1925  		*(*uint8)((unsafe.Pointer)(p)) = uint8(rest)
  1926  	}
  1927  	return
  1928  }
  1929  
  1930  // XORReadUint32AddRotate XORs argument "b" with a pseudo-random value.
  1931  // The result is the same (but faster) as:
  1932  //
  1933  // 	x := make([]byte, len(b))
  1934  // 	mathrand.ReadUint32AddRotate(x)
  1935  // 	for i := range b {
  1936  // 		b[i] ^= x[i]
  1937  // 	}
  1938  func (prng *PRNG) XORReadUint32AddRotate(b []byte) (l int, err error) {
  1939  	l = len(b)
  1940  	s := (uintptr)((unsafe.Pointer)(&b[0]))
  1941  	p := s
  1942  	e := s + uintptr(l)
  1943  	{
  1944  		state32Temp0 := prng.state32[0]
  1945  		for f := e - 4; p <= f; p += 4 {
  1946  			state32Temp0 += primeNumber32bit0
  1947  			state32Temp0 = rotateLeft32(state32Temp0, 32)
  1948  			*(*uint32)((unsafe.Pointer)(p)) ^= state32Temp0
  1949  		}
  1950  		prng.state32[0] = state32Temp0
  1951  	}
  1952  
  1953  	if e-p == 0 {
  1954  		return
  1955  	}
  1956  	rest := prng.Uint32AddRotate()
  1957  	if e-p >= 2 {
  1958  		*(*uint16)((unsafe.Pointer)(p)) ^= uint16(rest)
  1959  		rest >>= 16
  1960  		p += 2
  1961  	}
  1962  	if e-p >= 1 {
  1963  		*(*uint8)((unsafe.Pointer)(p)) ^= uint8(rest)
  1964  	}
  1965  	return
  1966  }
  1967  
  1968  // ReadUint32AddRotateWithReseed is an analog of math/rand.Read. This random
  1969  // numbers could easily be predicted (it's not an analog of crypto/rand.Read).
  1970  //
  1971  // "Reseed" forces to use a new seed (generated using XORShift method) on setting value to
  1972  // a pointer `& 0xff < 4`. Sometimes it allows to improve randomness of random numbers with a
  1973  // small performance impact.
  1974  // This method makes sense only if len(b) is large enough (>= 256 bytes).
  1975  // Otherwise it could affect strongly performance or it will not improve the randomness.
  1976  //
  1977  // Applied PRNG method:
  1978  // Uint32AddRotate is a very fast (but weak) analog of `math/rand.Uint32`.
  1979  func (prng *PRNG) ReadUint32AddRotateWithReseed(b []byte) (l int, err error) {
  1980  	l = len(b)
  1981  	s := (uintptr)((unsafe.Pointer)(&b[0]))
  1982  	p := s
  1983  	e := s + uintptr(l)
  1984  	{
  1985  		state32Temp0 := prng.state32[0]
  1986  		for f := e - 4; p <= f; p += 4 {
  1987  			state32Temp0 += primeNumber32bit0
  1988  			state32Temp0 = rotateLeft32(state32Temp0, 32)
  1989  			*(*uint32)((unsafe.Pointer)(p)) = state32Temp0
  1990  			if p&0xff < 4 {
  1991  				continue
  1992  			}
  1993  			state32Temp0 = (uint32)(xorShift32(state32Temp0 ^ primeNumber32bit0))
  1994  		}
  1995  		prng.state32[0] = state32Temp0
  1996  	}
  1997  
  1998  	if e-p == 0 {
  1999  		return
  2000  	}
  2001  	rest := prng.Uint32AddRotate()
  2002  	if e-p >= 2 {
  2003  		*(*uint16)((unsafe.Pointer)(p)) = uint16(rest)
  2004  		rest >>= 16
  2005  		p += 2
  2006  	}
  2007  	if e-p >= 1 {
  2008  		*(*uint8)((unsafe.Pointer)(p)) = uint8(rest)
  2009  	}
  2010  	return
  2011  }
  2012  
  2013  // XORReadUint32AddRotateWithReseed XORs argument "b" with a pseudo-random value.
  2014  // The result is the same (but faster) as:
  2015  //
  2016  // 	x := make([]byte, len(b))
  2017  // 	mathrand.ReadUint32AddRotateWithReseed(x)
  2018  // 	for i := range b {
  2019  // 		b[i] ^= x[i]
  2020  // 	}
  2021  func (prng *PRNG) XORReadUint32AddRotateWithReseed(b []byte) (l int, err error) {
  2022  	l = len(b)
  2023  	s := (uintptr)((unsafe.Pointer)(&b[0]))
  2024  	p := s
  2025  	e := s + uintptr(l)
  2026  	{
  2027  		state32Temp0 := prng.state32[0]
  2028  		for f := e - 4; p <= f; p += 4 {
  2029  			state32Temp0 += primeNumber32bit0
  2030  			state32Temp0 = rotateLeft32(state32Temp0, 32)
  2031  			*(*uint32)((unsafe.Pointer)(p)) ^= state32Temp0
  2032  			if p&0xff < 4 {
  2033  				continue
  2034  			}
  2035  			state32Temp0 = (uint32)(xorShift32(state32Temp0 ^ primeNumber32bit0))
  2036  		}
  2037  		prng.state32[0] = state32Temp0
  2038  	}
  2039  
  2040  	if e-p == 0 {
  2041  		return
  2042  	}
  2043  	rest := prng.Uint32AddRotate()
  2044  	if e-p >= 2 {
  2045  		*(*uint16)((unsafe.Pointer)(p)) ^= uint16(rest)
  2046  		rest >>= 16
  2047  		p += 2
  2048  	}
  2049  	if e-p >= 1 {
  2050  		*(*uint8)((unsafe.Pointer)(p)) ^= uint8(rest)
  2051  	}
  2052  	return
  2053  }
  2054  
  2055  // ReadUint32AddIfShiftXOR is an analog of math/rand.Read. This random
  2056  // numbers could easily be predicted (it's not an analog of crypto/rand.Read).
  2057  //
  2058  // Applied PRNG method:
  2059  // Uint32AddIfShiftXOR is a very fast (but weak) analog of `math/rand.Uint32`.
  2060  func (prng *PRNG) ReadUint32AddIfShiftXOR(b []byte) (l int, err error) {
  2061  	l = len(b)
  2062  	s := (uintptr)((unsafe.Pointer)(&b[0]))
  2063  	p := s
  2064  	e := s + uintptr(l)
  2065  	{
  2066  		state32Temp0 := prng.state32[0]
  2067  		for f := e - 4; p <= f; p += 4 {
  2068  			state32Temp0 += primeNumber32bit1
  2069  			if state32Temp0&0x02 == 0 {
  2070  				state32Temp0 ^= state32Temp0 >> 16
  2071  			}
  2072  			*(*uint32)((unsafe.Pointer)(p)) = state32Temp0
  2073  		}
  2074  		prng.state32[0] = state32Temp0
  2075  	}
  2076  
  2077  	if e-p == 0 {
  2078  		return
  2079  	}
  2080  	rest := prng.Uint32AddIfShiftXOR()
  2081  	if e-p >= 2 {
  2082  		*(*uint16)((unsafe.Pointer)(p)) = uint16(rest)
  2083  		rest >>= 16
  2084  		p += 2
  2085  	}
  2086  	if e-p >= 1 {
  2087  		*(*uint8)((unsafe.Pointer)(p)) = uint8(rest)
  2088  	}
  2089  	return
  2090  }
  2091  
  2092  // XORReadUint32AddIfShiftXOR XORs argument "b" with a pseudo-random value.
  2093  // The result is the same (but faster) as:
  2094  //
  2095  // 	x := make([]byte, len(b))
  2096  // 	mathrand.ReadUint32AddIfShiftXOR(x)
  2097  // 	for i := range b {
  2098  // 		b[i] ^= x[i]
  2099  // 	}
  2100  func (prng *PRNG) XORReadUint32AddIfShiftXOR(b []byte) (l int, err error) {
  2101  	l = len(b)
  2102  	s := (uintptr)((unsafe.Pointer)(&b[0]))
  2103  	p := s
  2104  	e := s + uintptr(l)
  2105  	{
  2106  		state32Temp0 := prng.state32[0]
  2107  		for f := e - 4; p <= f; p += 4 {
  2108  			state32Temp0 += primeNumber32bit1
  2109  			if state32Temp0&0x02 == 0 {
  2110  				state32Temp0 ^= state32Temp0 >> 16
  2111  			}
  2112  			*(*uint32)((unsafe.Pointer)(p)) ^= state32Temp0
  2113  		}
  2114  		prng.state32[0] = state32Temp0
  2115  	}
  2116  
  2117  	if e-p == 0 {
  2118  		return
  2119  	}
  2120  	rest := prng.Uint32AddIfShiftXOR()
  2121  	if e-p >= 2 {
  2122  		*(*uint16)((unsafe.Pointer)(p)) ^= uint16(rest)
  2123  		rest >>= 16
  2124  		p += 2
  2125  	}
  2126  	if e-p >= 1 {
  2127  		*(*uint8)((unsafe.Pointer)(p)) ^= uint8(rest)
  2128  	}
  2129  	return
  2130  }
  2131  
  2132  // ReadUint32AddIfShiftXORWithReseed is an analog of math/rand.Read. This random
  2133  // numbers could easily be predicted (it's not an analog of crypto/rand.Read).
  2134  //
  2135  // "Reseed" forces to use a new seed (generated using XORShift method) on setting value to
  2136  // a pointer `& 0xff < 4`. Sometimes it allows to improve randomness of random numbers with a
  2137  // small performance impact.
  2138  // This method makes sense only if len(b) is large enough (>= 256 bytes).
  2139  // Otherwise it could affect strongly performance or it will not improve the randomness.
  2140  //
  2141  // Applied PRNG method:
  2142  // Uint32AddIfShiftXOR is a very fast (but weak) analog of `math/rand.Uint32`.
  2143  func (prng *PRNG) ReadUint32AddIfShiftXORWithReseed(b []byte) (l int, err error) {
  2144  	l = len(b)
  2145  	s := (uintptr)((unsafe.Pointer)(&b[0]))
  2146  	p := s
  2147  	e := s + uintptr(l)
  2148  	{
  2149  		state32Temp0 := prng.state32[0]
  2150  		for f := e - 4; p <= f; p += 4 {
  2151  			state32Temp0 += primeNumber32bit1
  2152  			if state32Temp0&0x02 == 0 {
  2153  				state32Temp0 ^= state32Temp0 >> 16
  2154  			}
  2155  			*(*uint32)((unsafe.Pointer)(p)) = state32Temp0
  2156  			if p&0xff < 4 {
  2157  				continue
  2158  			}
  2159  			state32Temp0 = (uint32)(xorShift32(state32Temp0 ^ primeNumber32bit0))
  2160  		}
  2161  		prng.state32[0] = state32Temp0
  2162  	}
  2163  
  2164  	if e-p == 0 {
  2165  		return
  2166  	}
  2167  	rest := prng.Uint32AddIfShiftXOR()
  2168  	if e-p >= 2 {
  2169  		*(*uint16)((unsafe.Pointer)(p)) = uint16(rest)
  2170  		rest >>= 16
  2171  		p += 2
  2172  	}
  2173  	if e-p >= 1 {
  2174  		*(*uint8)((unsafe.Pointer)(p)) = uint8(rest)
  2175  	}
  2176  	return
  2177  }
  2178  
  2179  // XORReadUint32AddIfShiftXORWithReseed XORs argument "b" with a pseudo-random value.
  2180  // The result is the same (but faster) as:
  2181  //
  2182  // 	x := make([]byte, len(b))
  2183  // 	mathrand.ReadUint32AddIfShiftXORWithReseed(x)
  2184  // 	for i := range b {
  2185  // 		b[i] ^= x[i]
  2186  // 	}
  2187  func (prng *PRNG) XORReadUint32AddIfShiftXORWithReseed(b []byte) (l int, err error) {
  2188  	l = len(b)
  2189  	s := (uintptr)((unsafe.Pointer)(&b[0]))
  2190  	p := s
  2191  	e := s + uintptr(l)
  2192  	{
  2193  		state32Temp0 := prng.state32[0]
  2194  		for f := e - 4; p <= f; p += 4 {
  2195  			state32Temp0 += primeNumber32bit1
  2196  			if state32Temp0&0x02 == 0 {
  2197  				state32Temp0 ^= state32Temp0 >> 16
  2198  			}
  2199  			*(*uint32)((unsafe.Pointer)(p)) ^= state32Temp0
  2200  			if p&0xff < 4 {
  2201  				continue
  2202  			}
  2203  			state32Temp0 = (uint32)(xorShift32(state32Temp0 ^ primeNumber32bit0))
  2204  		}
  2205  		prng.state32[0] = state32Temp0
  2206  	}
  2207  
  2208  	if e-p == 0 {
  2209  		return
  2210  	}
  2211  	rest := prng.Uint32AddIfShiftXOR()
  2212  	if e-p >= 2 {
  2213  		*(*uint16)((unsafe.Pointer)(p)) ^= uint16(rest)
  2214  		rest >>= 16
  2215  		p += 2
  2216  	}
  2217  	if e-p >= 1 {
  2218  		*(*uint8)((unsafe.Pointer)(p)) ^= uint8(rest)
  2219  	}
  2220  	return
  2221  }
  2222  
  2223  // ReadUint32Xorshift is an analog of math/rand.Read. This random
  2224  // numbers could easily be predicted (it's not an analog of crypto/rand.Read).
  2225  //
  2226  // Applied PRNG method:
  2227  // Uint32Xorshift is a very fast (but weak) analog of `math/rand.Uint32`.
  2228  //
  2229  // See also: https://en.wikipedia.org/wiki/Xorshift
  2230  func (prng *PRNG) ReadUint32Xorshift(b []byte) (l int, err error) {
  2231  	l = len(b)
  2232  	s := (uintptr)((unsafe.Pointer)(&b[0]))
  2233  	p := s
  2234  	e := s + uintptr(l)
  2235  	{
  2236  		state32Temp0 := prng.state32[0]
  2237  		for f := e - 4; p <= f; p += 4 {
  2238  			state32Temp0 ^= state32Temp0 << 13
  2239  			state32Temp0 ^= state32Temp0 >> 17
  2240  			state32Temp0 ^= state32Temp0 << 5
  2241  			*(*uint32)((unsafe.Pointer)(p)) = state32Temp0
  2242  		}
  2243  		prng.state32[0] = state32Temp0
  2244  	}
  2245  
  2246  	if e-p == 0 {
  2247  		return
  2248  	}
  2249  	rest := prng.Uint32Xorshift()
  2250  	if e-p >= 2 {
  2251  		*(*uint16)((unsafe.Pointer)(p)) = uint16(rest)
  2252  		rest >>= 16
  2253  		p += 2
  2254  	}
  2255  	if e-p >= 1 {
  2256  		*(*uint8)((unsafe.Pointer)(p)) = uint8(rest)
  2257  	}
  2258  	return
  2259  }
  2260  
  2261  // XORReadUint32Xorshift XORs argument "b" with a pseudo-random value.
  2262  // The result is the same (but faster) as:
  2263  //
  2264  // 	x := make([]byte, len(b))
  2265  // 	mathrand.ReadUint32Xorshift(x)
  2266  // 	for i := range b {
  2267  // 		b[i] ^= x[i]
  2268  // 	}
  2269  func (prng *PRNG) XORReadUint32Xorshift(b []byte) (l int, err error) {
  2270  	l = len(b)
  2271  	s := (uintptr)((unsafe.Pointer)(&b[0]))
  2272  	p := s
  2273  	e := s + uintptr(l)
  2274  	{
  2275  		state32Temp0 := prng.state32[0]
  2276  		for f := e - 4; p <= f; p += 4 {
  2277  			state32Temp0 ^= state32Temp0 << 13
  2278  			state32Temp0 ^= state32Temp0 >> 17
  2279  			state32Temp0 ^= state32Temp0 << 5
  2280  			*(*uint32)((unsafe.Pointer)(p)) ^= state32Temp0
  2281  		}
  2282  		prng.state32[0] = state32Temp0
  2283  	}
  2284  
  2285  	if e-p == 0 {
  2286  		return
  2287  	}
  2288  	rest := prng.Uint32Xorshift()
  2289  	if e-p >= 2 {
  2290  		*(*uint16)((unsafe.Pointer)(p)) ^= uint16(rest)
  2291  		rest >>= 16
  2292  		p += 2
  2293  	}
  2294  	if e-p >= 1 {
  2295  		*(*uint8)((unsafe.Pointer)(p)) ^= uint8(rest)
  2296  	}
  2297  	return
  2298  }
  2299  
  2300  // ReadUint32XorshiftWithReseed is an analog of math/rand.Read. This random
  2301  // numbers could easily be predicted (it's not an analog of crypto/rand.Read).
  2302  //
  2303  // "Reseed" forces to use a new seed (generated using XORShift method) on setting value to
  2304  // a pointer `& 0xff < 4`. Sometimes it allows to improve randomness of random numbers with a
  2305  // small performance impact.
  2306  // This method makes sense only if len(b) is large enough (>= 256 bytes).
  2307  // Otherwise it could affect strongly performance or it will not improve the randomness.
  2308  //
  2309  // Applied PRNG method:
  2310  // Uint32Xorshift is a very fast (but weak) analog of `math/rand.Uint32`.
  2311  //
  2312  // See also: https://en.wikipedia.org/wiki/Xorshift
  2313  func (prng *PRNG) ReadUint32XorshiftWithReseed(b []byte) (l int, err error) {
  2314  	l = len(b)
  2315  	s := (uintptr)((unsafe.Pointer)(&b[0]))
  2316  	p := s
  2317  	e := s + uintptr(l)
  2318  	{
  2319  		state32Temp0 := prng.state32[0]
  2320  		for f := e - 4; p <= f; p += 4 {
  2321  			state32Temp0 ^= state32Temp0 << 13
  2322  			state32Temp0 ^= state32Temp0 >> 17
  2323  			state32Temp0 ^= state32Temp0 << 5
  2324  			*(*uint32)((unsafe.Pointer)(p)) = state32Temp0
  2325  			if p&0xff < 4 {
  2326  				continue
  2327  			}
  2328  			state32Temp0 = (uint32)(xorShift32(state32Temp0 ^ primeNumber32bit0))
  2329  		}
  2330  		prng.state32[0] = state32Temp0
  2331  	}
  2332  
  2333  	if e-p == 0 {
  2334  		return
  2335  	}
  2336  	rest := prng.Uint32Xorshift()
  2337  	if e-p >= 2 {
  2338  		*(*uint16)((unsafe.Pointer)(p)) = uint16(rest)
  2339  		rest >>= 16
  2340  		p += 2
  2341  	}
  2342  	if e-p >= 1 {
  2343  		*(*uint8)((unsafe.Pointer)(p)) = uint8(rest)
  2344  	}
  2345  	return
  2346  }
  2347  
  2348  // XORReadUint32XorshiftWithReseed XORs argument "b" with a pseudo-random value.
  2349  // The result is the same (but faster) as:
  2350  //
  2351  // 	x := make([]byte, len(b))
  2352  // 	mathrand.ReadUint32XorshiftWithReseed(x)
  2353  // 	for i := range b {
  2354  // 		b[i] ^= x[i]
  2355  // 	}
  2356  func (prng *PRNG) XORReadUint32XorshiftWithReseed(b []byte) (l int, err error) {
  2357  	l = len(b)
  2358  	s := (uintptr)((unsafe.Pointer)(&b[0]))
  2359  	p := s
  2360  	e := s + uintptr(l)
  2361  	{
  2362  		state32Temp0 := prng.state32[0]
  2363  		for f := e - 4; p <= f; p += 4 {
  2364  			state32Temp0 ^= state32Temp0 << 13
  2365  			state32Temp0 ^= state32Temp0 >> 17
  2366  			state32Temp0 ^= state32Temp0 << 5
  2367  			*(*uint32)((unsafe.Pointer)(p)) ^= state32Temp0
  2368  			if p&0xff < 4 {
  2369  				continue
  2370  			}
  2371  			state32Temp0 = (uint32)(xorShift32(state32Temp0 ^ primeNumber32bit0))
  2372  		}
  2373  		prng.state32[0] = state32Temp0
  2374  	}
  2375  
  2376  	if e-p == 0 {
  2377  		return
  2378  	}
  2379  	rest := prng.Uint32Xorshift()
  2380  	if e-p >= 2 {
  2381  		*(*uint16)((unsafe.Pointer)(p)) ^= uint16(rest)
  2382  		rest >>= 16
  2383  		p += 2
  2384  	}
  2385  	if e-p >= 1 {
  2386  		*(*uint8)((unsafe.Pointer)(p)) ^= uint8(rest)
  2387  	}
  2388  	return
  2389  }
  2390  
  2391  // ReadUint32PCG is an analog of math/rand.Read. This random
  2392  // numbers could easily be predicted (it's not an analog of crypto/rand.Read).
  2393  //
  2394  // Applied PRNG method:
  2395  // See also: https://en.wikipedia.org/wiki/Permuted_congruential_generator
  2396  func (prng *PRNG) ReadUint32PCG(b []byte) (l int, err error) {
  2397  	l = len(b)
  2398  	s := (uintptr)((unsafe.Pointer)(&b[0]))
  2399  	p := s
  2400  	e := s + uintptr(l)
  2401  	{
  2402  		pcgStateTemp := prng.pcgState
  2403  		for f := e - 4; p <= f; p += 4 {
  2404  			x := pcgStateTemp
  2405  			count := int(x >> 59)
  2406  			pcgStateTemp = x*pcgMultiplier + pcgIncrement
  2407  			x ^= x >> 18
  2408  			*(*uint32)((unsafe.Pointer)(p)) = rotateRight32(uint32(x>>27), count)
  2409  		}
  2410  		prng.pcgState = pcgStateTemp
  2411  	}
  2412  
  2413  	if e-p == 0 {
  2414  		return
  2415  	}
  2416  	rest := prng.Uint32PCG()
  2417  	if e-p >= 2 {
  2418  		*(*uint16)((unsafe.Pointer)(p)) = uint16(rest)
  2419  		rest >>= 16
  2420  		p += 2
  2421  	}
  2422  	if e-p >= 1 {
  2423  		*(*uint8)((unsafe.Pointer)(p)) = uint8(rest)
  2424  	}
  2425  	return
  2426  }
  2427  
  2428  // XORReadUint32PCG XORs argument "b" with a pseudo-random value.
  2429  // The result is the same (but faster) as:
  2430  //
  2431  // 	x := make([]byte, len(b))
  2432  // 	mathrand.ReadUint32PCG(x)
  2433  // 	for i := range b {
  2434  // 		b[i] ^= x[i]
  2435  // 	}
  2436  func (prng *PRNG) XORReadUint32PCG(b []byte) (l int, err error) {
  2437  	l = len(b)
  2438  	s := (uintptr)((unsafe.Pointer)(&b[0]))
  2439  	p := s
  2440  	e := s + uintptr(l)
  2441  	{
  2442  		pcgStateTemp := prng.pcgState
  2443  		for f := e - 4; p <= f; p += 4 {
  2444  			x := pcgStateTemp
  2445  			count := int(x >> 59)
  2446  			pcgStateTemp = x*pcgMultiplier + pcgIncrement
  2447  			x ^= x >> 18
  2448  			*(*uint32)((unsafe.Pointer)(p)) ^= rotateRight32(uint32(x>>27), count)
  2449  		}
  2450  		prng.pcgState = pcgStateTemp
  2451  	}
  2452  
  2453  	if e-p == 0 {
  2454  		return
  2455  	}
  2456  	rest := prng.Uint32PCG()
  2457  	if e-p >= 2 {
  2458  		*(*uint16)((unsafe.Pointer)(p)) ^= uint16(rest)
  2459  		rest >>= 16
  2460  		p += 2
  2461  	}
  2462  	if e-p >= 1 {
  2463  		*(*uint8)((unsafe.Pointer)(p)) ^= uint8(rest)
  2464  	}
  2465  	return
  2466  }
  2467  
  2468  // ReadUint32PCGWithReseed is an analog of math/rand.Read. This random
  2469  // numbers could easily be predicted (it's not an analog of crypto/rand.Read).
  2470  //
  2471  // "Reseed" forces to use a new seed (generated using XORShift method) on setting value to
  2472  // a pointer `& 0xff < 4`. Sometimes it allows to improve randomness of random numbers with a
  2473  // small performance impact.
  2474  // This method makes sense only if len(b) is large enough (>= 256 bytes).
  2475  // Otherwise it could affect strongly performance or it will not improve the randomness.
  2476  //
  2477  // Applied PRNG method:
  2478  // See also: https://en.wikipedia.org/wiki/Permuted_congruential_generator
  2479  func (prng *PRNG) ReadUint32PCGWithReseed(b []byte) (l int, err error) {
  2480  	l = len(b)
  2481  	s := (uintptr)((unsafe.Pointer)(&b[0]))
  2482  	p := s
  2483  	e := s + uintptr(l)
  2484  	{
  2485  		pcgStateTemp := prng.pcgState
  2486  		for f := e - 4; p <= f; p += 4 {
  2487  			x := pcgStateTemp
  2488  			count := int(x >> 59)
  2489  			pcgStateTemp = x*pcgMultiplier + pcgIncrement
  2490  			x ^= x >> 18
  2491  			*(*uint32)((unsafe.Pointer)(p)) = rotateRight32(uint32(x>>27), count)
  2492  			if p&0xff < 4 {
  2493  				continue
  2494  			}
  2495  			pcgStateTemp = xorShift64(pcgStateTemp^primeNumber64bit0)<<1 + 1
  2496  		}
  2497  		prng.pcgState = pcgStateTemp
  2498  	}
  2499  
  2500  	if e-p == 0 {
  2501  		return
  2502  	}
  2503  	rest := prng.Uint32PCG()
  2504  	if e-p >= 2 {
  2505  		*(*uint16)((unsafe.Pointer)(p)) = uint16(rest)
  2506  		rest >>= 16
  2507  		p += 2
  2508  	}
  2509  	if e-p >= 1 {
  2510  		*(*uint8)((unsafe.Pointer)(p)) = uint8(rest)
  2511  	}
  2512  	return
  2513  }
  2514  
  2515  // XORReadUint32PCGWithReseed XORs argument "b" with a pseudo-random value.
  2516  // The result is the same (but faster) as:
  2517  //
  2518  // 	x := make([]byte, len(b))
  2519  // 	mathrand.ReadUint32PCGWithReseed(x)
  2520  // 	for i := range b {
  2521  // 		b[i] ^= x[i]
  2522  // 	}
  2523  func (prng *PRNG) XORReadUint32PCGWithReseed(b []byte) (l int, err error) {
  2524  	l = len(b)
  2525  	s := (uintptr)((unsafe.Pointer)(&b[0]))
  2526  	p := s
  2527  	e := s + uintptr(l)
  2528  	{
  2529  		pcgStateTemp := prng.pcgState
  2530  		for f := e - 4; p <= f; p += 4 {
  2531  			x := pcgStateTemp
  2532  			count := int(x >> 59)
  2533  			pcgStateTemp = x*pcgMultiplier + pcgIncrement
  2534  			x ^= x >> 18
  2535  			*(*uint32)((unsafe.Pointer)(p)) ^= rotateRight32(uint32(x>>27), count)
  2536  			if p&0xff < 4 {
  2537  				continue
  2538  			}
  2539  			pcgStateTemp = xorShift64(pcgStateTemp^primeNumber64bit0)<<1 + 1
  2540  		}
  2541  		prng.pcgState = pcgStateTemp
  2542  	}
  2543  
  2544  	if e-p == 0 {
  2545  		return
  2546  	}
  2547  	rest := prng.Uint32PCG()
  2548  	if e-p >= 2 {
  2549  		*(*uint16)((unsafe.Pointer)(p)) ^= uint16(rest)
  2550  		rest >>= 16
  2551  		p += 2
  2552  	}
  2553  	if e-p >= 1 {
  2554  		*(*uint8)((unsafe.Pointer)(p)) ^= uint8(rest)
  2555  	}
  2556  	return
  2557  }