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.
You might want to try PCG-Random, from http://www.pcg-random.org/
decent, fast, portable
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With