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)
你好像懂了。他们使用生成器给出该分布中的随机数。成交。
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)
你好像懂了。他们使用生成器给出该分布中的随机数。成交。