Not thoroughly tested, needs update for some Random changes in Swift
import Foundation | |
// http://xoshiro.di.unimi.it/xoshiro256starstar.c | |
protocol PseudoRandomNumberGenerator { | |
associatedtype ReturnValue | |
mutating func next() -> ReturnValue | |
} | |
struct Arc4Random: PseudoRandomNumberGenerator { | |
typealias ReturnValue = UInt32 | |
mutating func next() -> UInt32 { | |
return arc4random() | |
} | |
} | |
struct XoShiro256: PseudoRandomNumberGenerator { | |
typealias ReturnValue = UInt64 | |
private var seed: [UInt64] | |
// initialize with a new seed | |
init(withSeed seed: [UInt64]) { | |
precondition(seed.count == 4) | |
self.seed = seed | |
} | |
// initialize with arc4random seed values | |
init() { | |
seed = [ | |
UInt64(upper: arc4random(), lower: arc4random()), | |
UInt64(upper: arc4random(), lower: arc4random()), | |
UInt64(upper: arc4random(), lower: arc4random()), | |
UInt64(upper: arc4random(), lower: arc4random()) | |
] | |
} | |
mutating func next() -> UInt64 { | |
let result_starstar = rotl(x: seed[1] * 5, k: 7) * 9 | |
let scrambler = seed[1] << 17; | |
seed[2] ^= seed[0] | |
seed[3] ^= seed[1] | |
seed[1] ^= seed[2] | |
seed[0] ^= seed[3] | |
seed[2] ^= scrambler | |
seed[3] = rotl(x: seed[3], k: 45) | |
return result_starstar | |
} | |
// todo: implement jump | |
@inline(__always) | |
private func rotl(x: UInt64, k: UInt64) -> UInt64 { | |
return (x << k) | (x >> (64 - k)) | |
} | |
private static let jump_const: [UInt64] = [ 0x180ec6d33cfd0aba, 0xd5a61266f0c9392c, 0xa9582618e03fc9aa, 0x39abdc4529b1661c ] | |
} | |
extension UInt64 { | |
// create a 64-bit integer from two 32-bit integers | |
init(upper: UInt32, lower: UInt32) { | |
self.init(upper << 32 | lower) | |
} | |
} | |
var rand1 = XoShiro256() | |
print("xoshiro256") | |
print(rand1.next()) | |
print(rand1.next()) | |
print(rand1.next()) | |
var rand2 = Arc4Random() | |
print("arc4random") | |
print(rand2.next()) | |
print(rand2.next()) | |
print(rand2.next()) | |
// print(rand.next()) | |
// print(rand.next()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment