C++ генерирует хорошее случайное семя для psudo генераторов случайных чисел

Я пытаюсь генерировать хорошее случайное семя для psudo-генератора-случайных-чисел. Я думал, что получу мнения эксперта. сообщите мне - ли это плохой способ сделать его или если существуют намного лучшие пути.

#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()
6
задан Yu Hao 1 December 2013 в 02:55
поделиться

7 ответов

Определите хорошее. : -)

Важно ли быстро найти семя, или чтобы семя было как можно более случайным, независимо от того, сколько времени потребуется на сборку?

Для баланса - определенно не самого случайного, определенно не самого лучшего. самый быстрый ...

  • При первом вызове учитывайте системное время в миллисекундах.
  • Выполните это с помощью хеш-функции, например SHA-1.
  • Используйте результат как семя.

Это должно дать вам в основном случайные 160 бит, что составляет 10-50-ю или около того вариативности. На выполнение хэша уйдет доли секунды, так что это не молниеносно, но в прошлом для меня было хорошим балансом.

0
ответ дан 9 December 2019 в 20:41
поделиться

Хорошим генераторам псевдослучайных чисел не нужны "хорошие" начальные числа, любые начальные числа ( это отличается от бега к бегу) работает одинаково хорошо.

Использование системного времени напрямую - это нормально (и обычно). Также можно использовать / dev / random .

Если ваш генератор псевдослучайных чисел не подходит, даже выбор «хорошего» начального числа не поможет. Замени его, если сможешь.

Предложения: Твистер Мерсенна очень популярен. Вот предшественник, который будет работать даже в самых ограниченных системах.

3
ответ дан 9 December 2019 в 20:41
поделиться

«Хорошие» генераторы, «плохие генераторы» это ничего не значит. «Любой, кто рассматривает арифметические методы получения случайных цифр, , конечно, в состоянии греха ». - Джон фон Нейман. Каждый такой генератор - это просто детерминированный алгоритм. очень важно иметь начальные состояния (seed), которые приносят достаточную энтропию. В зависимости от того, что вам нужно, вам следует проверить качество генератора. Метод Монте-Карло - очень хорошая оценка генератора псевдослучайных чисел.

1
ответ дан 9 December 2019 в 20:41
поделиться

Возможно, вам стоит предпочесть / dev / urandom / перед / dev / random . Последний блокируется в Linux, если доступной энтропии недостаточно, что может легко произойти, если программа работает на машине без взаимодействия с пользователем. Если вы не можете открыть / dev / urandom , вы можете создать исключение вместо использования запасного варианта.

0
ответ дан 9 December 2019 в 20:41
поделиться

Хорошо, вот изменения, которые я внес после рассмотрения вашего вклада. Кстати, спасибо за все!

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()
2
ответ дан 9 December 2019 в 20:41
поделиться

Код, который читает из / dev / random, кажется неправильным: вы в стиле C преобразуете адрес своего символьного буфера в random_seed_a (здесь плагин для приведений C ++) и игнорируете все, что вы на самом деле читаете из / dev / random (попробуйте * reinterpret_cast (mblock) .

/ dev / random уже должен быть хорошим источником энтропии, поэтому, если он доступен, не искажайте значение другими данными и просто используйте его в качестве семени напрямую. Если в / dev / random данных недостаточно, я бы просто использовал время и использовал его само по себе, а не xor'ing его с чем-то.

5
ответ дан 9 December 2019 в 20:41
поделиться

Традиционно мы использовали первый или второй пользовательский ввод для заполнения наших значений, поскольку время (от тиков до миллисекунд), которое требуется им для ответа, довольно варьируется.

1
ответ дан 9 December 2019 в 20:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: