Почему я получаю одну и ту же последовательность для каждого запуска с помощью std:: random_device с mingw gcc4.8.1?
Я использую следующий код для тестирования библиотеки c++ <random>
.
Почему я получаю точно такую же последовательность для каждого запуска скомпилированного исполняемого файла? Является ли rd()
детерминированным при компиляции? Как получить разные выходные данные для каждого прогона?
GCC 4.8.1 на Windows 7 64bit. Использование дистрибутива MinGW из http://nuwen.net/mingw.html
EDIT: Я тестировал один и тот же код с Visual Studio. Нет проблем. Выходы не являются детерминированными. Это может быть ошибка в mingw gcc 4.8.1, которую я использовал.
#include <iostream>
#include <random>
using namespace std;
int main(){
random_device rd;
mt19937 mt(rd());
uniform_int_distribution<int> dist(0,99);
for (int i = 0; i< 16; ++i){
cout<<dist(mt)<<" ";
}
cout <<endl;
}
Ответы
Ответ 1
Из http://en.cppreference.com/w/cpp/numeric/random/random_device:
Обратите внимание, что std:: random_device может быть реализовано в терминах механизма псевдослучайных чисел, если для реализации не доступен недетерминированный источник (например, аппаратное устройство).
Я ожидал бы достойной реализации, по крайней мере, запустив RNG.
Изменить: Я подозреваю, что они преднамеренно решили выполнить одну и ту же последовательность каждый раз, чтобы сделать очевидным тот факт, что поток не был таким случайным, как обещали.
Ответ 2
Я получил подтвержденный ответ от STL от MSFT:
В отличие от VC, GCC не реализовал random_device недетерминированно в Windows. Boost, поэтому вы можете использовать Boost.Random.
Ответ 3
Вам может потребоваться передать параметр конструктору:
https://gcc.gnu.org/onlinedocs/gcc-4.9.1/libstdc++/api/a00899.html
Ответ 4
-
GCC не реализует rd.entropy() правильно - он всегда возвращает 0 (по крайней мере, в Mac OS X).
-
К сожалению, похоже, что нет никакого способа смешать дополнительную энтропию в random_device, что важно, потому что обычно/часто (смотрите Linux/dev/random и /dev/urandom и в реализации Intel RDRAND) реализует генератор псевдослучайных чисел под капотом. Я бы хотел улучшить свой результат, введя что-то, что я считаю случайным, чтобы смешиваться с тем, что производит его источник энтропии. Опять же, поскольку это устройство (или модуль ядра) внутренне реализует криптографический алгоритм для обработки битов энтропии, которые он получает для генерации своего вывода, я хотел бы иметь возможность "рандомизировать" этот процесс больше, введя мои собственные данные, чтобы смешивать их с любыми энтропия, которую выбирает устройство.
Например, рассмотрим Java SecureRandom(). Это не позволяет вам установить семя (которое действительно будет преобразовывать его в PRNG), но оно будет радостно смешивать то, что вы предоставляете, тем, что оно использует, чтобы "рандомизировать" свой вывод еще больше. p >
-
Я лично предпочитаю RDRAND. Небольшая сборная библиотека с компактным интерфейсом C. Вот ссылки:
fooobar.com/info/54026/...
fooobar.com/info/54027/...
Блог Intel в библиотеке RDRAND и ссылка для скачивания