5

我需要一个“随机”数字生成器,它为 Windows、Mac、Linux、iOS 和 Android 上的给定种子产生相同的结果。现在我尝试了,std::rand但遗憾的是 Windows 和 Mac 之间的结果不同。boost::random_int_generatorboost::mt19937

有谁知道在所有平台上可靠运行的(C++)实现?

编辑1:

更具体地说,boost::mt19937Windows 和 Mac 上的数字之间的差异表明,在 Windows 上会生成 (2) 个额外的数字块。它看起来很奇怪,因为大多数数字是相同的,这些块只存在于 Windows 上。

编辑2:

boost::mt19937在所有平台上可靠地工作。我们的问题不是那里的错误。

4

3 回答 3

3

如果你不需要太高质量的 RNG,你可以根据这里的描述将它自己实现为单线:https ://en.wikipedia.org/wiki/Linear_congruential_generator线性同余根最近的名字很糟糕,但出于许多实际目的,它们很好。

只要你小心使用保证大小的类型(uint32_t 等),你应该在所有平台上都可以。

如果您需要质量更好的 RNG,您可以再次自己实现 Mersenne Twister ( https://en.wikipedia.org/wiki/Mersenne_Twister ),但会更复杂。

另一种方法是在 CTR 模式(使用一些预定义的密钥)中使用 AES(或任何其他块密码,如 Chacha20)作为您的 PRNG;它将具有最著名的(加密)质量:-)。您不需要太多编码,但您需要链接 AES 实现(它们广泛可用)。

编辑:示例伪代码来说明基于加密的 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)
  }
}

相当容易和非常随机。

于 2015-06-04T16:46:28.013 回答
3

您可能想尝试 PCG-Random,来自http://www.pcg-random.org/

体面,快速,便携

于 2015-06-04T23:46:40.410 回答
2

不同的数字导致了我们使用的一段glm代码。他们使用不确定的参数评估顺序,这对于几乎随机的目的来说很好,但在你想要确定的数字时(显然)就不行了。因此,我们根据我们的目的更正了代码,并成功地boost::mt19937在 Windows、Mac、Linux、Android 和 iOS 上使用。

对困惑感到抱歉。

于 2015-06-11T12:34:04.793 回答