c ++为伪随机数生成器生成一个好的随机种子

时间:2010-04-14 20:17:26

标签: c++ random random-seed

我正在尝试为psudo-random数字生成器生成一个好的随机种子。我以为我会得到专家的意见。如果这是一种不好的方式,或者有更好的方法,请告诉我。

#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()

7 个答案:

答案 0 :(得分:5)

从/ dev / random读取的代码似乎是错误的:你是C风格将你的角色缓冲区的地址转换为random_seed_a(这里为C ++转换插件)并忽略你实际从/ dev / random读取的任何东西(试试) *reinterpret_cast<int*>(memblock)

/ dev / random应该已经是一个很好的熵源,所以如果它可用,不要将该值与任何其他数据一起污染,只需将其直接用作种子即可。如果/ dev / random中没有足够的数据,我只会依赖于时间并单独使用它而不是用某些东西进行xor'ing。

答案 1 :(得分:3)

好的伪随机数生成器不需要“好”种子,任何种子(与运行不同)都可以很好地工作。

直接使用系统时间很好(和常见)。使用/dev/random也没问题。

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

建议:Mersenne twister非常受欢迎。 Here's即使是最有限的系统也会运行的前体。

答案 2 :(得分: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()

答案 3 :(得分:1)

传统上,我们使用第一个或第二个用户输入将我们的​​值作为种子(tics到毫秒范围),它们响应的时间量变化很大。

答案 4 :(得分:1)

“好”的发电机,“坏发电机”它并不意味着什么。 “任何考虑产生随机数字的算术方法的人当然都处于罪恶状态。” - 约翰冯诺伊曼。 每个这样的发生器只是一种确定性算法。拥有足够熵的初始状态(种子)非常重要非常。 根据您的需要,您应该测试您的发电机质量。蒙特卡罗方法是伪随机数发生器的一个非常好的估计。

答案 5 :(得分:0)

定义好。 : - )

重要的是快速找到种子,或者种子尽可能随机,无论放在一起需要多长时间?

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

  • 首次调用时,请以毫秒为单位计算系统时间。
  • 通过哈希函数运行,如SHA-1。
  • 将结果用作种子。

那应该给你一个大多数随机的160位,这是10 ^ 50左右的可变性。哈希将花费一瞬间运行,所以这不是闪电般快,但对我来说过去是一个很好的平衡。

答案 6 :(得分:0)

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