寻找可重放/有点无状态的PRNG算法

时间:2015-03-06 20:31:05

标签: algorithm prng

我正在寻找一个伪随机数生成器,它可以重放"和#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,但这个想法仍然是一样的。)

2 个答案:

答案 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;
}

随机数序列是“可重放的”,无状态,并且仅取决于初始值,即种子。

参考文献:

  1. 维基:Wiki

  2. 一篇详细数学的论文:paper