7

我正在尝试为伪随机数生成器生成一个好的随机种子。我想我会得到专家的意见。让我知道这是否是一种不好的方法,或者是否有更好的方法。

#include <iostream>
#include <cstdlib>
#include <fstream>
#include <ctime>

unsigned int good_seed()
{
    unsigned int random_seed, random_seed_a, random_seed_b; 
    std::ifstream file ("/dev/random", std::ios::binary);
    if (file.is_open())
    {
        char * memblock;
        int size = sizeof(int);
        memblock = new char [size];
        file.read (memblock, size);
        file.close();
        random_seed_a = int(memblock);
        delete[] memblock;
    }// end if
    else
    {
        random_seed_a = 0;
    }
    random_seed_b = std::time(0);
    random_seed = random_seed_a xor random_seed_b;
    return random_seed;
} // end good_seed()
4

7 回答 7

5

从 /dev/random 读取的代码似乎是错误的:您使用 C 风格将字符缓冲区的地址转换为 random_seed_a (此处插入 C++ 转换)并忽略您实际从 /dev/random 读取的任何内容(尝试*reinterpret_cast<int*>(memblock).

/dev/random 应该已经是一个很好的熵源,所以如果它可用,就不可能用任何其他数据污染值,直接将其用作种子。如果 /dev/random 中没有足够的数据,我会退回到时间并单独使用它,而不是用某些东西对它进行异或运算。

于 2010-04-14T21:02:02.660 回答
4

好的伪随机数生成器不需要“好的”种子,任何种子(从运行到运行不同)都同样有效。

直接使用系统时间很好(并且很常见)。使用/dev/random也不错。

如果你的伪随机数生成器不好,即使选择一个“好”的种子也无济于事。如果可以,请更换它。

意见建议:梅森捻线机是相当受推崇的。这是一个可以在最有限的系统上运行的先驱。

于 2010-04-14T21:02:37.217 回答
2

好的,这是我在考虑您的意见后所做的更改。顺便感谢您所做的一切!

unsigned int good_seed()
{
    unsigned int random_seed, random_seed_a, random_seed_b; 
    std::ifstream file ("/dev/urandom", std::ios::binary);
    if (file.is_open())
    {
        char * memblock;
        int size = sizeof(int);
        memblock = new char [size];
        file.read (memblock, size);
        file.close();
        random_seed_a = *reinterpret_cast<int*>(memblock);
        delete[] memblock;
    }// end if
    else
    {
        random_seed_a = 0;
    }
    random_seed_b = std::time(0);
    random_seed = random_seed_a xor random_seed_b;
    std::cout << "random_seed_a = " << random_seed_a << std::endl;
    std::cout << "random_seed_b = " << random_seed_b << std::endl;
    std::cout << " random_seed =  " << random_seed << std::endl;
    return random_seed;
} // end good_seed()
于 2010-04-14T23:42:42.120 回答
1

“好”生成器,“坏生成器”没有任何意义。“任何考虑产生随机数字的算术方法的人当然都处于犯罪状态。” ——约翰·冯·诺依曼。每个这样的生成器都只是一个确定性算法。拥有能够带来足够熵的初始状态(种子)非常重要。根据您的需要,您应该测试您的发电机质量。蒙特卡洛方法是一个非常好的伪随机数发生器估计器。

于 2010-04-14T21:28:30.673 回答
1

也许你应该更/dev/urandom/喜欢/dev/random. 如果没有足够的可用熵,后者会在 Linux 上阻塞,如果程序在没有用户交互的机器上运行,则很容易发生这种情况。如果您无法打开/dev/urandom,您可以抛出异常而不是使用回退。

于 2010-04-14T21:10:39.727 回答
1

传统上,我们使用第一个或第二个用户输入来播种我们的值,因为它们响应所需的时间(抽动到毫秒范围)是相当可变的。

于 2010-04-14T20:22:47.100 回答
0

定义好。:-)

快速找到种子是否重要,或者无论需要多长时间,种子都尽可能随机?

为了平衡 - 绝对不是最随机的,绝对不是最快的......

  • 首次调用时,获取系统时间,以毫秒为单位。
  • 通过散列函数运行它,比如 SHA-1。
  • 使用结果作为种子。

这应该给你一个主要是随机的 160 位,这是 10 ^ 50 左右的可变性。哈希将需要一秒钟的时间来运行,所以这不是闪电般的快,但在过去对我来说是一个很好的平衡。

于 2010-04-14T20:19:36.163 回答