我正在寻找一个伪随机数生成器,它可以重放"和#34;无国籍的"。让我详细说明:我需要能够根据随机函数的参数重新获取伪随机数。例如(C风格的伪代码):
int x1 = random(1);
int x2 = random(2);
// and so on with lots of random() calls in between
int new_x1 = random(1);
// now new_x1 is like a "replay" of x1, so x1 == new_x1
论证的类型并不重要(我可以根据需要进行类型转换),返回值不必是int
;最终我需要8位值。
问题是:什么是一个好的PRNG算法,它满足下一个伪随机值由参数控制的要求,而不是每次调用时更新的内部状态?我不知道如何使用如下的糟糕解决方案:
int random(int input) {
srand(input);
return rand();
}
这必须在每次调用时初始化PRNG,这看起来很昂贵。 (我用标准srand() / rand()
说明了这一点,我知道有更好的算法,比如Mersenne Twister,但这个想法仍然是一样的。)
答案 0 :(得分:0)
这里可能有用的一种方法是使用像AES或三重DES这样的分组密码。您的伪随机生成器可以是
int pseudorandomValue(int input) {
return encryptUsingAES(input);
}
这是无状态的,伪随机的(因为AES的输出在统计上应该与随机无法区分)和无状态。
希望这有帮助!
答案 1 :(得分:0)
您可以使用基于Xorshift [1,2]的PRNG。此PRNG使用先前的随机数生成下一个。与AES相比,该实施非常有效。
对于32位实现:
uint32_t next_rand(uint32_t prev)
{
prev ^= prev << 13;
prev ^= prev >> 17;
prev ^= prev << 5;
return prev;
}
对于64位实现:
uint64_t next_rand(uint64_t prev)
{
prev ^= prev << 21;
prev ^= prev >> 35;
prev ^= prev << 4;
return prev;
}
随机数序列是“可重放的”,无状态,并且仅取决于初始值,即种子。
参考文献: