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

发布于 2024-08-28 21:48:53 字数 782 浏览 4 评论 0原文

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

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

I am trying to generate a good random seed for a psudo-random number generator. I thought I'd get the expert's opinions. let me know if this is a bad way of doing it or if there are much better ways.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

妥活 2024-09-04 21:48:53

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

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

The code that reads from /dev/random seems wrong: you're C-style casting the address of your character buffer into random_seed_a (plug for C++ casts here) and ignoring anything you actually read from /dev/random (try *reinterpret_cast<int*>(memblock).

/dev/random should already be a good entropy source, so if it's available don't possibly taint the value with any other data and just use it as the seed directly. If there isn't enough data in /dev/random I would just fall back on the time and use that by itself rather than xor'ing it with something.

韬韬不绝 2024-09-04 21:48:53

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

直接使用系统时间很好(而且很常见)。使用 /dev/random 也可以。

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

建议:梅森扭曲器 非常受好评。 这里 甚至可以在最有限的系统上运行的先驱。

Good pseudo-random number generators don't need a "good" seed, any seed (that's different from run to run) works equally well.

Using system time directly is fine (and common). Using /dev/random is also fine.

If your pseudo-random number generator isn't good, even picking a "good" seed won't help. Replace it if you can.

Suggestions: Mersenne twister is a pretty well regarded. Here's a precursor which will run on even the most limited of systems.

香橙ぽ 2024-09-04 21:48:53

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

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

Ok here's the changes I made after considering your input. Thanks for everything by the way!

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()
深巷少女 2024-09-04 21:48:53

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

Traditionally, we've used first or second user input to seed our values as the (tics to millisecond range) amount of time it takes them to respond is pretty variable.

远山浅 2024-09-04 21:48:53

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

Maybe you should prefer /dev/urandom/ over /dev/random. The latter blocks on Linux if there is not enough entropy available, which can easily happen if the program runs on a machine without user interaction. In case you cannot open /dev/urandom, you could throw an exception instead of using a fallback.

三寸金莲 2024-09-04 21:48:53

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

"Good" generators, "Bad generators" it doesn't mean anything.
"Anyone who considers arithmetical methods of producing random digits is, of course, in a state of sin." - John von Neumann.
Every such generator is just a deterministic algorithm. It's very important to have initial states ( seed ) that bring enough entropy.
Depending on what you need, you should test your generator quality. Monte Carlo method is a very good estimator of a pseudo random number generator.

难忘№最初的完美 2024-09-04 21:48:53

定义好。 :-)

快速找到种子重要吗?或者无论拼凑起来需要多长时间,种子都尽可能随机?

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

  • 第一次调用时,取系统时间,以毫秒为单位。
  • 通过哈希函数(如 SHA-1)运行该函数。
  • 使用结果作为种子。

这将为您提供大部分随机的 160 位,即 10^50 左右的可变性。哈希值需要一瞬间才能运行,所以这不是闪电般的快,但对我来说过去是一个很好的平衡。

Define good. :-)

Is it important to find a seed quickly, or that the seed be as random as possible no matter how long it takes to put together?

For a balance - definitely not the most random, definitely not the fastest...

  • When it's first called, take the system time, in milliseconds.
  • Run that through a hash function, like SHA-1.
  • Use the result as the seed.

That should give you a mostly-random 160 bits, which is 10^50th or so of variability. The hash will take a split second to run, so this isn't lightning fast, but has been a good balance in the past for me.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文