跨平台可再生数字生成器

Crossplatform reproducible number generator

本文关键字:数字 再生 跨平台      更新时间:2023-10-16

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

有没有人知道一个(c++)的实现,可以在所有平台上可靠地工作?

编辑1:

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

编辑2:

boost::mt19937在所有平台上可靠地工作。我们的问题不是一个bug。

如果你不需要高质量的RNG,你可以根据这里的描述自己实现它:https://en.wikipedia.org/wiki/Linear_congruential_generator线性同同族最近名声不好,但对于许多实际用途来说,它们还不错。

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

如果你需要更高质量的RNG,同样你可以自己实现Mersenne Twister (https://en.wikipedia.org/wiki/Mersenne_Twister),但它会更复杂。

另一种方法是在CTR模式下使用AES(或任何其他块密码,如chachha20)(使用一些预定义的密钥)作为您的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)
  }
}

您可以尝试从http://www.pcg-random.org/

体面、快速、便携

不同的数字产生了我们使用的glm代码。它们使用未确定的参数求值顺序,这对于几乎随机的目的是可以的,但当您想要确定的数字时(显然)就不是了。因此,我们根据我们的目的修改了代码,并成功地在Windows, Mac, Linux, Android和iOS上使用了boost::mt19937

很抱歉造成了混乱