Эквивалент /dev/urandom в Windows?

Мое приложение хотело бы получить случайное число, желательно с энтропией, если оно доступно, но не нуждается в криптографическом качестве и хотело бы убедиться, что вызов не блокируется, если пул энтропийных систем исчерпан (например, на сервере в ферме). Я знаю CryptGenRandom (http://msdn.microsoft.com/en-us/library/windows/desktop/aa379942(v=vs.85).aspx), но его поведение в отношении блокировки при неблагоприятных условиях энтропии не определен. В Unix/dev/urandom поддерживает этот прецедент. Доступна ли в Windows эквивалентная функциональность? Я бы предпочел избегать использования несистемного RNG просто для того, чтобы получить неблокирующую семантику.

Ответ 1

Для игрушечного приложения вы можете использовать rand(), но реализация в Windows имеет, как известно, низкое качество.

Лучше всего просто включить в свою программу подходящий генератор псевдослучайных чисел. Mersenne Twister - хороший выбор ИМО, особенно, поскольку существует множество доступных реализаций (в том числе в стандартной библиотеке С++ 11 и в Boost).

Ответ 2

Если мне нужно неблокирующее поведение на случайных числах, я обычно предгенерирую n чисел и сохраняю их в переменной памяти: ie, если я знаю, что мне понадобится 30 случайных чисел в секунду, для их вычисления (включая блоки) требуется 3 секунды,, тогда я буду предварительно генерировать 300, пока основной код загружается, сохраняет их в массиве или векторе и использует их при необходимости; в то время как я их использую, я генерирую другой в отдельном потоке каждый раз, когда я использую его, заменяя использованное случайное число на вновь сгенерированное и переходя к следующему в списке, таким образом, когда я достигаю предела (в этом случае 300) Я знаю, когда я могу просто начать снова в начале моего массива/вектора/списка, и все случайные числа будут свежими и будут неблокируемыми (поскольку они предварительно сгенерированы).

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

Надеюсь, это поможет, поскольку я не мог вместить это все в комментарий :)

Ответ 3

Вы можете подождать, пока одно хорошее семя будет заполнено энтропией и последует совету GMasucci, чтобы создать длинный список случайных чисел.

Если ваша система уже не скомпрометирована, кажется, что хорошее семя достаточно для генерации серии несвязанных чисел, как описано в http://www.2uo.de/myths-about-urandom/

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

Источник семян? Два или более доверенных программного обеспечения, которые с меньшей вероятностью будут скомпрометированы. Я пытаюсь размыть предсказуемость функций, которые используют функции времени в качестве семени: local rand_function() + некоторая переменная delay + mysql rand(). Оттуда, список псевдослучайных чисел, порожденных некоторой хорошей библиотекой.