跨平台可重复数字生成器
Crossplatform reproducible number generator
我需要一个 "random" 数字生成器,它在 Windows、Mac、Linux、iOS 和 Linux 上为给定的种子生成相同的结果Android。现在我尝试 std::rand
和 boost::random_int_generator
与 boost::mt19937
但遗憾的是 Windows 和 Mac 之间的结果不同。
有人知道在所有平台上都能可靠运行的 (C++) 实现吗?
编辑 1:
更具体地说,Windows 和 Mac 上 boost::mt19937
的数字之间的差异表明,Windows 上有 (2) 个额外的数字块正在生成。看起来真的很奇怪,因为大多数数字是相同的,而这些块仅出现在 Windows.
上
编辑 2:
boost::mt19937
在所有平台上都能可靠地工作。我们的问题不是那里的错误。
如果你不需要太高质量的RNG,你可以按照这里的描述自己实现一个单线:https://en.wikipedia.org/wiki/Linear_congruential_generator线性同余氏族最近名声不好,但是对于许多实际用途他们都很好。
只要您谨慎使用大小有保证的类型(uint32_t 等),您在所有平台上都应该没问题。
如果您需要更高质量的随机数生成器,您也可以自己实现 Mersenne Twister (https://en.wikipedia.org/wiki/Mersenne_Twister),但会更复杂。
另一种方法是在 CTR 模式(使用一些预定义的密钥)下使用 AES(或任何其他块密码,如 Chacha20)作为 PRNG;它将具有最著名的(加密)质量 :-)。您不需要编写太多代码,但您需要 link 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)
}
}
相当简单且非常随机。
您可能想尝试 PCG-Random,来自 http://www.pcg-random.org/
体面、快速、便携
不同的数字导致我们使用了一段 glm
代码。他们使用不确定的参数评估顺序,这对于几乎随机的目的来说很好,但当你想要确定性数字时(显然)。因此,我们出于我们的目的更正了代码,并成功地在 Windows、Mac、Linux、Android 和 iOS.[=12 上使用了 boost::mt19937
=]
抱歉造成混淆。
我需要一个 "random" 数字生成器,它在 Windows、Mac、Linux、iOS 和 Linux 上为给定的种子生成相同的结果Android。现在我尝试 std::rand
和 boost::random_int_generator
与 boost::mt19937
但遗憾的是 Windows 和 Mac 之间的结果不同。
有人知道在所有平台上都能可靠运行的 (C++) 实现吗?
编辑 1:
更具体地说,Windows 和 Mac 上 boost::mt19937
的数字之间的差异表明,Windows 上有 (2) 个额外的数字块正在生成。看起来真的很奇怪,因为大多数数字是相同的,而这些块仅出现在 Windows.
编辑 2:
boost::mt19937
在所有平台上都能可靠地工作。我们的问题不是那里的错误。
如果你不需要太高质量的RNG,你可以按照这里的描述自己实现一个单线:https://en.wikipedia.org/wiki/Linear_congruential_generator线性同余氏族最近名声不好,但是对于许多实际用途他们都很好。
只要您谨慎使用大小有保证的类型(uint32_t 等),您在所有平台上都应该没问题。
如果您需要更高质量的随机数生成器,您也可以自己实现 Mersenne Twister (https://en.wikipedia.org/wiki/Mersenne_Twister),但会更复杂。
另一种方法是在 CTR 模式(使用一些预定义的密钥)下使用 AES(或任何其他块密码,如 Chacha20)作为 PRNG;它将具有最著名的(加密)质量 :-)。您不需要编写太多代码,但您需要 link 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)
}
}
相当简单且非常随机。
您可能想尝试 PCG-Random,来自 http://www.pcg-random.org/
体面、快速、便携
不同的数字导致我们使用了一段 glm
代码。他们使用不确定的参数评估顺序,这对于几乎随机的目的来说很好,但当你想要确定性数字时(显然)。因此,我们出于我们的目的更正了代码,并成功地在 Windows、Mac、Linux、Android 和 iOS.[=12 上使用了 boost::mt19937
=]
抱歉造成混淆。