Created
November 21, 2018 03:20
-
-
Save steverichey/24b0b7549170bc48563cb99c19c832f7 to your computer and use it in GitHub Desktop.
Not thoroughly tested, needs update for some Random changes in Swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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