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.

abergmeier
  • 13,224
  • 13
  • 64
  • 120
  • 1
    What about [Mersenne Twister](http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html)? – transistor09 Jun 04 '15 at 16:38
  • 4
    `boost::mt19937` should provide consistent results, can you provide the a [Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve) – Shafik Yaghmour Jun 04 '15 at 16:43
  • @ShafikYaghmour Sadly not yet. See the edit for a better description of the problem. I will try to create a small example later. – abergmeier Jun 05 '15 at 09:06

3 Answers3

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.

No-Bugs Hare
  • 1,557
  • 14
  • 15
3

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

decent, fast, portable

Severin Pappadeux
  • 18,636
  • 3
  • 38
  • 64
  • Question is about crossplatform number generation, I am unable to see that point is mentioned in the page you linked. – unlut Oct 04 '20 at 12:07
  • @unlut Well, PCG-Random is known to be cross-platform reproducible good quality RNG – Severin Pappadeux Oct 04 '20 at 15:38
  • 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. – unlut Oct 04 '20 at 19:25
  • @unlut Well, there is a paper https://www.cs.hmc.edu/tr/hmc-cs-2014-0905.pdf with features described. NumPy settled on PCG XSL RR 128/64 (LCG) as their default RNG – Severin Pappadeux Oct 04 '20 at 20:30
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.

abergmeier
  • 13,224
  • 13
  • 64
  • 120