C++生成超级随机数

Generate super random number in c++

C++11 引入了允许生成非常随机数的 class,它还创建了均匀分布的随机数。还有生成种子的实现(用于使随机数生成器更随机的数字)。

我正在尝试创建一个生成介于最小值和最大值之间的随机数的函数,但我遇到了问题。该函数只生成一次种子和随机数。换句话说,当我调用该函数时,它会一直给我相同的数字。

下面是代码,我尝试生成一堆种子,随机选择其中一个,将那个种子用于 RNG,最后生成一个随机数。

int Utils::GenerateSuperRandomNum(int min, int max)
{
    //Seed a the RNG
    int randNum;
    int randIndex;
    seed_seq seq{ 1, 2, 3, 4, 5 };
    vector<int> seeds(5 * max);
    uniform_int_distribution<int> rngDistribution(min, max);    //Generates number in the range min to max.

    //Generate our seed numbers.
    seq.generate(seeds.begin(), seeds.end());

    //Generate random index bewteen 0 and size - 1.
    srand(seeds.at(0));
    randIndex = rand() % seeds.size(); 

    //Seed the RNG with a random seed from our vector.
    mt19937 rngGenerator(seeds.at(randIndex)); 

    //Get a random number.
    randNum = rngDistribution(rngGenerator);

    return randNum;
}

种子 不会 使(伪)随机数生成器更加随机。它为生成 可重现的 随机数序列提供了起点。

这意味着,如果您提供完全相同的种子,您将获得完全相同的结果。

通过使用随机数生成器来生成它自己的种子来使随机数生成器更 "random" 有点像试图通过拉靴带来提升自己。如果这只是为了好玩,时间是一个足够随机的种子,如果你正在做超级间谍加密,你需要一个提供真正随机事件的 h/w 设备。

您可以尝试使用此服务,我不知道它是否有效或只是 NSA 试图欺骗您。 https://www.random.org

seed_seq seq{ 1, 2, 3, 4, 5 };
vector<int> seeds(5 * max);
uniform_int_distribution<int> rngDistribution(min, max);    //Generates number in the range min to max.

//Generate our seed numbers.
seq.generate(seeds.begin(), seeds.end());

seq 总是输入相同的 {1,2,3,4,5} 所以总是有相同的状态。由于它具有相同的状态,因此 seeds.at(0) 始终是相同的值。

//Generate random index bewteen 0 and size - 1.
srand(seeds.at(0));

由于 srand 每次都以相同的值作为种子,因此每次都以相同的状态开始。因为它每次都收到相同的值,所以它总是以相同的状态开始。 rand 使用的状态相同。

randIndex = rand() % seeds.size(); 

由于 rand 始终具有与 srand 相同的状态,因此每次都会生成相同的第一个数字。

 mt19937 rngGenerator(seeds.at(randIndex)); 

由于 randIndex 始终是相同的值,因此 seeds.at(randIndex) 始终是相同的值。由于 rngGenerator 始终以相同的值作为种子,因此它始终具有相同的状态。

randNum = rngDistribution(rngGenerator);

由于 rngDistribution 始终具有相同的状态,因此它始终产生相同的值。

这显然是个问题。简单的解决方法是根据 CPU 温度、时间或其他经常变化的值来播种。


基本上,您已经严重考虑了这一点。它被设计成这样使用:

int Utils::GenerateSuperRandomNum(int min, int max) {
    static mt19937 rngGenerator(std::random_device{}());
    std::uniform_int_distribution<int> rngDistribution(min, max);
    return rngDistribution(rngGenerator);
}

std::random_device{}() 基于魔法生成一个模糊的随机数字,希望是硬件,比如 CPU 温度或其他东西。它可能会很慢或有其他问题,因此每个程序只能使用一次。即,播种 faster/better 生成器。

static mt19937 rngGenerator( 创建一个单一的全局生成器,它在第一次调用函数时被播种,并且永远不会再次播种。这是完美的,因为我们希望它被初始化一次,然后从那时起就做它的魔法。使用 rand 等其他生成器不会增加任何熵,所以不要那样做。我们也不想重新播种它,因为这可能会意外地减少而不是增加随机性。

std::uniform_int_distribution<int> rngDistribution(min, max);rngDistribution(rngGenerator)你好像懂了。他们使用生成器给出该分布中的随机数。成交。