简体   繁体   English

Crossplatform可重现的数字生成器

[英]Crossplatform reproducible number generator

I need a "random" number generator, which produces the same result for a given seed on Windows, Mac, Linux, iOS and Android. 我需要一个“随机”数字生成器,它可以为Windows,Mac,Linux,iOS和Android上的给定种子生成相同的结果。 Now I tried std::rand and boost::random_int_generator with boost::mt19937 but sadly the result is different between Windows and Mac. 现在我用boost::mt19937尝试了std::randboost::random_int_generator boost::mt19937但遗憾的是Windows和Mac之间的结果有所不同。

Does anyone know of a (C++) implementation, that works reliably on all platforms? 有谁知道(C ++)实现,它在所有平台上都可靠地运行?

EDIT 1: 编辑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. 更具体地说,Windows和Mac上来自boost::mt19937数字之间的区别显示,在Windows上有(2)个生成的附加数字块。 It looks really strange because the majority of numbers is the same with these blocks being only present on Windows. 它看起来很奇怪,因为大多数数字都是相同的,这些块只存在于Windows上。

EDIT 2: 编辑2:

boost::mt19937 works reliably on all platforms. boost::mt19937可以在所有平台上可靠地运行。 Our problems were not a bug there. 我们的问题不是那里的错误。

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. 如果你不需要太高质量的RNG,你可以根据这里的描述自己实现它: https//en.wikipedia.org/wiki/Linear_congruential_generator线性同余一族最近有一个很糟糕的名字,但出于许多实际目的,它们很好。

As long as you're careful with using only guaranteed-size types (uint32_t etc.), you should be fine on all the platforms. 只要你小心使用只有保证大小的类型(uint32_t等),你应该在所有平台上都没问题。

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. 如果您需要质量更好的RNG,您可以再次实施Mersenne Twister( https://en.wikipedia.org/wiki/Mersenne_Twister ),但会更复杂。

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; 另一种方法是在CTR模式下使用AES(或任何其他块密码,如Chacha20)(使用一些预定义的密钥)作为您的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). 它不需要太多编码,但您需要链接AES实现(它们可以广泛使用)。

EDIT: example pseudo-code to illustrate crypto-based PRNG: 编辑:示例伪代码来说明基于加密的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. 相当简单,随意。

You might want to try PCG-Random, from http://www.pcg-random.org/ 你可能想尝试PCG-Random,来自http://www.pcg-random.org/

decent, fast, portable 体面,快速,便携

The different numbers resulted in a piece of glm code we used. 不同的数字导致了我们使用的一段glm代码。 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. 所以我们为了我们的目的更正了代码,并在Windows,Mac,Linux,Android和iOS上成功使用了boost::mt19937

Sorry for the confusion. 对困惑感到抱歉。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM