v8.run/go/exp@v0.0.26-0.20230226010534-afcdbd3f782d/fastrand/alg/xoshiro256plusplus/xoshiro256plusplus.go (about) 1 /****************************************************************************** 2 3 Original C code: https://prng.di.unimi.it/xoshiro256plusplus.c 4 Written in 2019 by David Blackman and Sebastiano Vigna (vigna@acm.org) 5 6 To the extent possible under law, the author has dedicated all copyright 7 and related and neighboring rights to this software to the public domain 8 worldwide. This software is distributed without any warranty. 9 10 See <http://creativecommons.org/publicdomain/zero/1.0/>. 11 12 *******************************************************************************/ 13 14 package xoshiro256plusplus 15 16 import ( 17 "sync" 18 19 "v8.run/go/exp/fastrand/alg/splitmix64" 20 ) 21 22 type State [4]uint64 23 24 func rotl(x uint64, k uint) uint64 { 25 return (x << k) | (x >> (64 - k)) 26 } 27 28 func (s *State) Next() uint64 { 29 var result uint64 = rotl(s[0]+s[3], 23) + s[0] 30 var t uint64 = s[1] << 17 31 32 s[2] ^= s[0] 33 s[3] ^= s[1] 34 s[1] ^= s[2] 35 s[0] ^= s[3] 36 37 s[2] ^= t 38 39 s[3] = rotl(s[3], 45) 40 41 return result 42 } 43 44 func (s *State) init(seed uint64) { 45 seed = splitmix64.Splitmix64(&seed) 46 s[0] = splitmix64.Splitmix64(&seed) 47 s[1] = splitmix64.Splitmix64(&seed) 48 s[2] = splitmix64.Splitmix64(&seed) 49 s[3] = splitmix64.Splitmix64(&seed) 50 } 51 52 // NewState initializes xoshiro256++ state. 53 func NewState() State { 54 var s State 55 s.init(splitmix64.Next()) 56 return s 57 } 58 59 // NewStateWithSeed initializes xoshiro256++ state with a seed. 60 func NewStateWithSeed(seed uint64) State { 61 var s State 62 s.init(seed) 63 return s 64 } 65 66 const seed uint64 = 9674114761913717981 67 68 var gState State = NewStateWithSeed(seed) 69 var mu sync.Mutex 70 71 func Next() uint64 { 72 mu.Lock() 73 v := gState.Next() 74 mu.Unlock() 75 return v 76 }