# Deterministic "randomness" in Swift

**URL:** <https://forums.swift.org/t/deterministic-randomness-in-swift/20835>\
**Category:** Using Swift\
**Created:** [February 23, 2019, 7:04pm UTC](https://forums.swift.org/t/deterministic-randomness-in-swift/20835 "2019-02-23T19:04:01Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jumhyn](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jumhyn/32/3891_2.png) [@Jumhyn](https://forums.swift.org/u/Jumhyn)\
**Post date:** [February 23, 2019, 7:04pm UTC](https://forums.swift.org/t/deterministic-randomness-in-swift/20835/1 "2019-02-23T19:04:01Z")

</div>

Is there any easy way to create reproducible pseudo-random numbers with Swift currently. It would be useful for e.g. unit testing where a large amount of unstructured data is desired, but you want any failures to be reproducible and debuggable. Currently, my solution has been to call `po array.shuffle().description` from the debugger and then paste that into my test code as a constant, but I would love it if there were, some other solution such as a `SeededRandomNumberGenerator` type. Is there a better solution to this that exists today?

---

<div class="post-metadata">

**Author:** ![Martin](https://avatars.discourse-cdn.com/v4/letter/m/73ab20/32.png) [@Martin](https://forums.swift.org/u/Martin)\
**Post date:** [February 23, 2019, 7:24pm UTC](https://forums.swift.org/t/deterministic-randomness-in-swift/20835/2 "2019-02-23T19:24:20Z")

</div>

Some thoughts which might be helpful or not:

- ~~The seed randomization can be suppressed for debugging purposes by setting the environment variable SWIFT\_DETERMINISTIC\_HASHING=1, compare [PSA: The stdlib now uses randomly seeded hash values - #3 by lorentey](https://forums.swift.org/t/psa-the-stdlib-now-uses-randomly-seeded-hash-values/10789/3)~~ **Edit:** That is nonsense, I mixed up two different topics, sorry for that. See @Alejandro's post below.
- [Howard Lovatt](https://forums.swift.org/u/hlovatt) suggested a seedable random number generator here: [SE-0202: Random Unification - #62 by hlovatt](https://forums.swift.org/t/se-0202-random-unification/11313/62).
- [GamePlayKit](https://developer.apple.com/documentation/gameplaykit) offers some (seedable) random number generators.

---

<div class="post-metadata">

**Author:** ![Jumhyn](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jumhyn/32/3891_2.png) [@Jumhyn](https://forums.swift.org/u/Jumhyn)\
**Post date:** [February 23, 2019, 7:34pm UTC](https://forums.swift.org/t/deterministic-randomness-in-swift/20835/3 "2019-02-23T19:34:59Z")

</div>

Cool, didn't realize that `SWIFT_DETERMINISTIC_HASHING` made all other randomness deterministic as well. I still think that having it be a compiler flag is a bit harsh since there may be production environments where you want the security of randomly seeded hashing in one part of the program, and deterministic-but-random-looking numbers in another. Importing `GamePlayKit` does seem to be the best solution, but (a) is relatively undiscoverable compared to `SystemRandomNumberGenerator` in the standard library, and (b) importing a whole framework designed for games into a program that may have nothing to do with games just for the random number generator seems like overkill.

---

<div class="post-metadata">

**Author:** ![Martin](https://avatars.discourse-cdn.com/v4/letter/m/73ab20/32.png) [@Martin](https://forums.swift.org/u/Martin)\
**Post date:** [February 23, 2019, 7:39pm UTC](https://forums.swift.org/t/deterministic-randomness-in-swift/20835/4 "2019-02-23T19:39:51Z")

</div>

I did not re-read all of [SE-0202: Random Unification](https://forums.swift.org/t/se-0202-random-unification/11313), that thread my contain more information about why the standard library does not provide _some_ seedable PRNG.

---

<div class="post-metadata">

**Author:** ![Jumhyn](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jumhyn/32/3891_2.png) [@Jumhyn](https://forums.swift.org/u/Jumhyn)\
**Post date:** [February 23, 2019, 7:43pm UTC](https://forums.swift.org/t/deterministic-randomness-in-swift/20835/5 "2019-02-23T19:43:05Z")

</div>

Ah, yeah looks like there's some good discussion in there. Thanks!

---

<div class="post-metadata">

**Author:** ![Nobody1707](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nobody1707/32/2169_2.png) [@Nobody1707](https://forums.swift.org/u/Nobody1707)\
**Post date:** [February 23, 2019, 7:55pm UTC](https://forums.swift.org/t/deterministic-randomness-in-swift/20835/6 "2019-02-23T19:55:59Z")

</div>

If you need a seedable PRNG, then here's a minimal implementation of XoroShiro256\*\*:

```swift
protocol PseudoRandomGenerator: RandomNumberGenerator {
    associatedtype State
    init(seed: State)
    init<Source: RandomNumberGenerator>(from source: inout Source)
}

extension PseudoRandomGenerator {
    init() {
        var source = SystemRandomNumberGenerator()
        self.init(from: &source)
    }
}

private func rotl(_ x: UInt64, _ k: UInt64) -> UInt64 {
    return (x << k) | (x >> (64 &- k))
}

struct Xoroshiro256StarStar: PseudoRandomGenerator {
    typealias State = (UInt64, UInt64, UInt64, UInt64)
    var state: State

    init(seed: State) {
        precondition(seed != (0, 0, 0, 0))
        state = seed
    }

    init<Source: RandomNumberGenerator>(from source: inout Source) {
        repeat {
            state = (source.next(), source.next(), source.next(), source.next())
        } while state == (0, 0, 0, 0)
    }

    mutating func next() -> UInt64 {
        let result = rotl(state.1 &* 5, 7) &* 9

        let t = state.1 << 17
        state.2 ^= state.0
        state.3 ^= state.1
        state.1 ^= state.2
        state.0 ^= state.3
    
        state.2 ^= t
    
        state.3 = rotl(state.3, 45)
    
        return result
    }
}

```

---

<div class="post-metadata">

**Author:** ![Alejandro](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/alejandro/32/46197_2.png) [@Alejandro](https://forums.swift.org/u/Alejandro)\
**Post date:** [February 23, 2019, 10:26pm UTC](https://forums.swift.org/t/deterministic-randomness-in-swift/20835/7 "2019-02-23T22:26:34Z")

</div>

SWIFT\_DETERMINISTIC\_HASHING does not affect any functionality brought from SE-0202. That environment variable only affects hashing. The stdlib does not currently include any prng for seedable reproduction, but it is something that is open for discussion for a future release. For now, the best way to achieve seedable randomness is to define your own prng like @Nobody1707 presented.

---

<div class="post-metadata">

**Author:** ![rxwei](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/rxwei/32/664_2.png) [@rxwei](https://forums.swift.org/u/rxwei)\
**Post date:** [February 24, 2019, 12:10am UTC](https://forums.swift.org/t/deterministic-randomness-in-swift/20835/8 "2019-02-24T00:10:18Z")

</div>

In the Swift for TensorFlow deep learning library we defined a [`SeedableRandomNumberGenerator`](https://github.com/tensorflow/swift-apis/blob/master/Sources/DeepLearning/Random.swift#L22) protocol and a few PRNGs: `PhiloxRandomNumberGenerator`, `ThreefryRandomNumberGenerator`, and `ARC4RandomNumberGenerator`.

---

<div class="post-metadata">

**Author:** ![yxckjhasdkjh](https://avatars.discourse-cdn.com/v4/letter/y/278dde/32.png) [@yxckjhasdkjh](https://forums.swift.org/u/yxckjhasdkjh)\
**Post date:** [February 25, 2019, 1:45pm UTC](https://forums.swift.org/t/deterministic-randomness-in-swift/20835/9 "2019-02-25T13:45:49Z")

</div>

Seedable PRNGs are also defined in the awesome [SwiftCheck](https://github.com/typelift/SwiftCheck/blob/master/Sources/SwiftCheck/Random.swift) library.

---

<div class="post-metadata">

**Author:** ![mackoj](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/mackoj/32/42395_2.png) [@mackoj](https://forums.swift.org/u/mackoj)\
**Post date:** [February 25, 2019, 9:22pm UTC](https://forums.swift.org/t/deterministic-randomness-in-swift/20835/10 "2019-02-25T21:22:08Z")

</div>

Recently on [pointfree.co](http://pointfree.co) they talk about how to do exactly this.

> **[Episode #48: Predictable Randomness: Part 2](https://www.pointfree.co/episodes/ep48-predictable-randomness-part-2)**
>
> This week we finally make our untestable Gen type testable. We'll compare several different ways of controlling Gen, consider how they affect Gen's API, and find ourselves face-to-face with yet another \`flatMap\`.

> **Previous Episodes about it**
>
> [Episode #47: Predictable Randomness: Part 1](https://www.pointfree.co/episodes/ep47-predictable-randomness-part-1)
> 
> [Episode #30: Composable Randomness](https://www.pointfree.co/episodes/ep30-composable-randomness)
> 
> [Random Zalgo Generator](https://www.pointfree.co/blog/posts/19-random-zalgo-generator)

---

<div class="post-metadata">

**Author:** ![paiv](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/paiv/32/4041_2.png) [@paiv](https://forums.swift.org/u/paiv)\
**Post date:** [March 4, 2019, 10:59pm UTC](https://forums.swift.org/t/deterministic-randomness-in-swift/20835/11 "2019-03-04T22:59:43Z")

</div>

PCG family of algorithms needs more love. [http://www.pcg-random.org/](http://www.pcg-random.org/)  
It is statistically good and simple to implement.

---

<div class="post-metadata">

**Author:** ![paiv](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/paiv/32/4041_2.png) [@paiv](https://forums.swift.org/u/paiv)\
**Post date:** [March 15, 2020, 11:57pm UTC](https://forums.swift.org/t/deterministic-randomness-in-swift/20835/12 "2020-03-15T23:57:17Z")

</div>

I have wrapped PCG into a package here: [GitHub - paiv/swift-pcg-random: PCG Random for Swift language](https://github.com/paiv/swift-pcg-random)

---

<div class="post-metadata">

**Author:** ![vincelupo](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/vincelupo/32/23703_2.png) [@vincelupo](https://forums.swift.org/u/vincelupo)\
**Post date:** [June 8, 2022, 5:20pm UTC](https://forums.swift.org/t/deterministic-randomness-in-swift/20835/13 "2022-06-08T17:20:43Z")

</div>

Swift's GameKit has seeded random capabilities.

> **[Shuffling an array with GameplayKit: arrayByShufflingObjects(in:) - a free...](https://www.hackingwithswift.com/read/35/6/shuffling-an-array-with-gameplaykit-arraybyshufflingobjectsin)**
>
> Learn Swift coding for iOS with these free tutorials

---

<div class="post-metadata">

**Author:** ![Jon\_Shier](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jon_shier/32/921_2.png) [@Jon\_Shier](https://forums.swift.org/u/Jon_Shier)\
**Post date:** [June 8, 2022, 5:23pm UTC](https://forums.swift.org/t/deterministic-randomness-in-swift/20835/14 "2022-06-08T17:23:32Z")

</div>

GameKit is not a Swift framework, so it doesn’t help in the general case.

---

<div class="post-metadata">

**Author:** ![tera](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tera/32/38201_2.png) [@tera](https://forums.swift.org/u/tera)\
**Post date:** [June 8, 2022, 5:36pm UTC](https://forums.swift.org/t/deterministic-randomness-in-swift/20835/15 "2022-06-08T17:36:57Z")

</div>

It would be quite useful to have deterministic randomness during development. I remember I was chasing a bug and succeeded only when I replaced all those various "random" calls to my wrappers which I based on some simple pseudorandom generator and thus removed the main sources of randomness (\*) to get the reproducible case I was finally able debug and fix. This approach has it's limitations (third party components or the system itself can have calls to random and it's not easy to patch that).

(\*) some remaining randomness (e.g. due to timing variation of code execution or due to effectively "random" memory addresses you are getting back from malloc) is inevitable.

---

<div class="post-metadata">

**Author:** ![Nobody1707](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nobody1707/32/2169_2.png) [@Nobody1707](https://forums.swift.org/u/Nobody1707)\
**Post date:** [June 8, 2022, 11:20pm UTC](https://forums.swift.org/t/deterministic-randomness-in-swift/20835/16 "2022-06-08T23:20:15Z")

</div>

There's really only two things missing required for a good general `PseudorandomNumberGenerator` protocol. Adding a `fill` method to the `RandomNumberGenerator` protocol, and the ability to require types to be trivially copyable.

A guarantee that `random(in:using:)` and friends will produce the same results when the given RNG produces the same sequence of random bits regardless of endianness would be nice, but we might already have that.

---

<div class="post-metadata">

**Author:** ![vincelupo](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/vincelupo/32/23703_2.png) [@vincelupo](https://forums.swift.org/u/vincelupo)\
**Post date:** [June 10, 2022, 3:33pm UTC](https://forums.swift.org/t/deterministic-randomness-in-swift/20835/17 "2022-06-10T15:33:30Z")

</div>

What? It's a built in apple Import. Easy to add to any project. It's like saying "I wish Sin and CoSin were available in swift", then someone responding "they are if you use Import Math" and then someone like you responding, "yea but that means you have use import". Sorry. I'm salty today.

---

<div class="post-metadata">

**Author:** ![Jumhyn](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jumhyn/32/3891_2.png) [@Jumhyn](https://forums.swift.org/u/Jumhyn)\
**Post date:** [June 10, 2022, 3:35pm UTC](https://forums.swift.org/t/deterministic-randomness-in-swift/20835/18 "2022-06-10T15:35:07Z")

</div>

> [@vincelupo](#):
>
> What? It's a built in apple Import.

Swift is available on platforms where GameKit doesn't exist, so a GameKit-based solution isn't really applicable to solving this problem _for the Swift language_.

---

<div class="post-metadata">

**Author:** ![vincelupo](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/vincelupo/32/23703_2.png) [@vincelupo](https://forums.swift.org/u/vincelupo)\
**Post date:** [June 10, 2022, 3:35pm UTC](https://forums.swift.org/t/deterministic-randomness-in-swift/20835/19 "2022-06-10T15:35:38Z")

</div>

> **[Generating random numbers in Swift - The.Swift.Dev.](https://theswiftdev.com/generating-random-numbers-in-swift/)**
>
> Learn everything what you'll ever need to generate random values in Swift using the latest methods and covering some old techniques.

Here's another page explaining how to use Import GameplayKit to get seeded random numbers.

---

<div class="post-metadata">

**Author:** ![vincelupo](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/vincelupo/32/23703_2.png) [@vincelupo](https://forums.swift.org/u/vincelupo)\
**Post date:** [June 10, 2022, 3:36pm UTC](https://forums.swift.org/t/deterministic-randomness-in-swift/20835/20 "2022-06-10T15:36:19Z")

</div>

Ah. Gotcha. Bummer

[Next page](https://forums.swift.org/t/deterministic-randomness-in-swift/20835.md?page=2)
