Crossplatform reproducible number generator
Asked Answered
T

3

5

I need a "random" number generator, which produces the same result for a given seed on Windows, Mac, Linux, iOS and Android. Now I tried std::rand and boost::random_int_generator with boost::mt19937 but sadly the result is different between Windows and Mac.

Does anyone know of a (C++) implementation, that works reliably on all platforms?

EDIT 1:

To be more specific, a diff between numbers from boost::mt19937 on Windows and Mac shows, that on Windows there are (2) additional blocks of numbers being generated. It looks really strange because the majority of numbers is the same with these blocks being only present on Windows.

EDIT 2:

boost::mt19937 works reliably on all platforms. Our problems were not a bug there.

Tupelo answered 4/6, 2015 at 16:33 Comment(3)
What about Mersenne Twister?Visconti
boost::mt19937 should provide consistent results, can you provide the a Minimal, Complete, and Verifiable exampleAdames
@ShafikYaghmour Sadly not yet. See the edit for a better description of the problem. I will try to create a small example later.Tupelo
T
2

The different numbers resulted in a piece of glm code we used. They use undetermined order of argument evaluation, which is fine for nearly random purposes, but not when you want deterministic numbers (obviously). So we corrected the code for our purposes and successfully use boost::mt19937 on Windows, Mac, Linux, Android and iOS.

Sorry for the confusion.

Tupelo answered 11/6, 2015 at 12:34 Comment(0)
C
4

If you don't need too-high-quality RNG, you can implement it yourself as a one-liner according to description here: https://en.wikipedia.org/wiki/Linear_congruential_generator Linear congruential gens got quite a bad name recently, but for many practical purposes they're fine.

As long as you're careful with using only guaranteed-size types (uint32_t etc.), you should be fine on all the platforms.

If you need better-quality RNG, once again you can implement Mersenne Twister (https://en.wikipedia.org/wiki/Mersenne_Twister) yourself, but it will be more complicated.

Yet another way is to use AES (or any other block cypher for that matter, like Chacha20) in CTR mode (using some predefined key) as your PRNG; it will be of the best known (cryptographic) quality :-). It won't take much coding on your side, but you'd need to link AES implementation (they're widely available).

EDIT: example pseudo-code to illustrate crypto-based PRNG:

class CryptoBasedPRNG {

 uint128_t key;
 uint128_t count;

 CryptoBasedPRNG(whatever-type seed) {
   //derive key and initial counter from seed
   //  we'll be using SHA256, but any other split should do (like odd bits/even bits of seed)
   uint256_t sha = sha256(seed);
   key = low_128bits(sha);
   count = high_128bits(sha);
  }

  uint128_t random_128_bits() {
    count += 1;//with wraparound
    return aes128(key,count);//encrypting 'count' as input data for aes128 (in ECB mode, if anybody asks about mode at this point)
  }
}

Rather easy and very random.

Chesnut answered 4/6, 2015 at 16:46 Comment(2)
Isn't boost::mt19937 a Mersenne Twister implementation?Tupelo
@abergmeier: yes, but OP says it produces different results on Mac and Windows :-(.Chesnut
S
3

You might want to try PCG-Random, from http://www.pcg-random.org/

decent, fast, portable

Spec answered 4/6, 2015 at 23:46 Comment(4)
Question is about crossplatform number generation, I am unable to see that point is mentioned in the page you linked.Nutriment
@Nutriment Well, PCG-Random is known to be cross-platform reproducible good quality RNGSpec
I see it is indeed (at least for integers) after inspecting, but where is this specified in the documentation? I think I should obtain that information without looking internals of the library.Nutriment
@Nutriment Well, there is a paper cs.hmc.edu/tr/hmc-cs-2014-0905.pdf with features described. NumPy settled on PCG XSL RR 128/64 (LCG) as their default RNGSpec
T
2

The different numbers resulted in a piece of glm code we used. They use undetermined order of argument evaluation, which is fine for nearly random purposes, but not when you want deterministic numbers (obviously). So we corrected the code for our purposes and successfully use boost::mt19937 on Windows, Mac, Linux, Android and iOS.

Sorry for the confusion.

Tupelo answered 11/6, 2015 at 12:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.