Заполнение генератора случайных чисел в .NET

У меня есть генератор псевдослучайных чисел (PRNG) с хорошими свойствами, который использует шесть UInt32с как состояние. Мне нужно найти разумный способ посеять его. Две очевидные возможности: 1) генерировать шесть случайных чисел, используя System.Randomи использовать их в качестве начальных чисел ; 2) сгенерировать два GUIDс с Guid.NewGuid(). Что было бы лучше?

Мне не нужна криптографическая безопасность.

15.12.2008 20:42:55
4 ОТВЕТА
РЕШЕНИЕ

Если это нужно UInt32, то Randomудобнее? просто Next(), Next()и Next()т. д. (и приведение) ... (используйте один и тот же Randomэкземпляр - не создавайте new Random()каждый раз).

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

4
15.12.2008 20:48:10
Вау, это было быстро :) Это кажется слишком малой случайностью, интуитивно. Но, вероятно, достаточно для моих целей. Не стоит зацикливаться на таких вещах.
Alexey Romanov 15.12.2008 20:52:06
@alexey_r - затем подключите радиоантенну и используйте белизну для генерации случайности ;-p Она должна прийти откуда-то ...
Marc Gravell♦ 15.12.2008 20:54:32
Что ж, вы не получите «больше случайности», если сгенерируете случайное число чисел, или запустите его случайное число раз и т. Д. Если вы используете System.Random, то оно будет случайным только в таком случае. И System.Random по умолчанию использует подсчет системных тиков. Если вам не нужен высокий уровень безопасности, этого достаточно.
lacop 15.12.2008 20:55:45
Я согласен с Марком. Использование PRNG для посева другого PRNG ничего не делает лучше или хуже.
Jon B 15.12.2008 21:01:33
Марк не сказал ничего положительного о посеве prng с другим prng imo. Фактом является то, что случайность уменьшается, если вы делаете это - следовательно, не создаете новый случайный случай каждый раз из-за того, как значение тиков меняется со временем (держу пари, вы получите многократное повторение «случайности»)
John Nicholas 15.05.2012 10:05:01

К сожалению, System.Random () также требует начального значения. По умолчанию используется текущий счетчик тиков, который является предсказуемым, а не случайным. Таким образом, вам нужно семя для Random, которое возвращает вас к вашему первоначальному вопросу ...

Я никогда раньше не использовал Guid.GetHashCode () в качестве начального числа, но моя 2-х секундная реакция - это не плохая идея.

4
15.12.2008 20:50:11
Является ли Guid.GetHashCode () менее предсказуемым, чем начальное значение по умолчанию?
Jon B 15.12.2008 20:59:19
Вам нужен крипто-парень, чтобы получить окончательный ответ, а я не один :) Я думаю, да, это менее предсказуемо. Время легко предсказуемо. Существуют различные алгоритмы GUID, и если вы знаете несколько других фрагментов данных (например, идентификатор оборудования), это также предсказуемо, но немного сложнее
JaredPar 15.12.2008 21:10:23
Я попробовал это на самом деле на днях, и оказалось, что GetHashCode в Guid был ужасным семенем для System.Random. На самом деле так плохо, что в течение 3 циклов на самом деле получилась точно такая же строка из 6 случайных чисел !!! Я был довольно удивлен, но решил не продолжать расследование.
nbevans 15.12.2008 21:24:26
@ Натан, как ты это проверил? Я только что сгенерировал 10000 GUID на моей машине и получил 0 дуплей. Использование powershell 1..10000 |% {[Guid] :: NewGuid (). GetHashCode () | выберите -unqiue
JaredPar 15.12.2008 21:43:06
Вы никогда не получите дубликат Guid, но они предсказуемы и не очень хорошие случайные семена.
Eric J. 9.09.2009 00:30:33

Нужна ли вам криптографическая защита или нет, почему бы просто не использовать System.Security.Cryptography.RNGCryptoServiceProvider для генерации случайных чисел? Если нет конкретной причины, как будто она слишком медленная, я не могу понять, почему вы бы ее не использовали. Поскольку это криптографический генератор случайных чисел, вы получите намного лучшие случайные числа, и вам не нужно беспокоиться о его заполнении.

4
15.12.2008 21:24:38
В общем, неплохая идея, но мне нужно, чтобы мой ГСЧ был разделяемым, а RNGCryptoServiceProviderэто не так.
Alexey Romanov 15.12.2008 21:39:38

Попробуйте это для вашего начального значения ...

(UInt32)Math.Pow(System.DateTime.Now.TimeOfDay.TotalMilliseconds, 11.0 / 7.0)

Он просто увеличивает текущее время на миллисекунды до 11/7-й степени, что просто произвольно. Вы можете поэкспериментировать с другими фракциями, чтобы увидеть, работают ли они лучше для вас.

Помните, что если десятичный эквивалент вашей дроби больше, чем примерно 2,5, вы можете получить переполнение, и ваше начальное значение будет равно нулю. :(

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

0
18.02.2013 19:21:16
Какую выгоду вы видите перед использованием System.DateTime.Now.TimeOfDay.TotalMilliseconds?
Alexey Romanov 18.02.2013 19:46:21
Хорошо, как насчет этого ... (UInt32)Math.Pow((new Random()).NextDouble() * (System.DateTime.Now.TimeOfDay.Ticks + 19), 11.0 / 7.0)
tvwxyz 22.02.2013 06:14:20