Так как компьютеры не могут выбирать случайные числа (могут ли они?), как это фактически генерируется случайное число. Например, в С# мы говорим,
Random.Next()
Что происходит внутри?
Так как компьютеры не могут выбирать случайные числа (могут ли они?), как это фактически генерируется случайное число. Например, в С# мы говорим,
Random.Next()
Что происходит внутри?
Вы можете проверить эту статью. Согласно документации конкретная реализация, используемая в .NET, основана на алгоритме генератора случайных чисел Дональда Э. Кнута. Для получения дополнительной информации см. D. Э. Кнут. "Искусство программирования, том 2: Семинумерные алгоритмы" . Addison-Wesley, Reading, MA, второе издание, 1981 г..
Так как компьютеры не могут выбирать случайные числа (могут ли они?)
Как отмечали другие, "Random" на самом деле псевдослучайно. Чтобы ответить на ваш вопрос в скобках: да, компьютеры могут выбирать по-настоящему случайные числа. Это намного дороже, чем простая целочисленная арифметика генератора псевдослучайных чисел и обычно не требуется. Однако есть приложения, в которых вы должны иметь непредсказуемую истинную случайность: криптография и онлайн-покер сразу приходят на ум. Если использовать предсказуемый источник псевдослучайности, то злоумышленники могут более легко расшифровать/подделать сообщения, а читеры могут выяснить, кто у них есть в руках.
В классах crypto.NET есть методы которые предоставляют случайные числа, подходящие для криптографии, или игры, в которых деньги находятся на линии. Что касается того, как они работают: литература по крипто-силовой случайности обширна; проконсультируйтесь с любым хорошим учебным пособием по криптографии в университете.
Специальное оборудование также существует для получения случайных бит. Если вам нужны случайные числа, полученные от атмосферного шума, см. Www.random.org.
Кнут очень хорошо относится к теме случайности.
Мы не очень хорошо разбираемся в случайности. Как можно предсказуемо быть случайным? И все же псевдослучайные последовательности могут казаться совершенно случайными при статистических тестах.
Существует три категории генераторов случайных чисел, которые усиливаются в комментарии выше.
Во-первых, у вас есть генераторы псевдослучайных чисел, где, если вы знаете текущее случайное число, легко вычислить следующий. Это позволяет легко преобразовать другие числа, если вы узнаете несколько.
Тогда есть криптографические алгоритмы, которые делают это намного сложнее. Я считаю, что они все еще являются псевдослучайными последовательностями (в отличие от того, что подразумевается выше в комментарии), но с очень важным свойством, что знание нескольких чисел в последовательности НЕ делает очевидным, как вычислить остальное. Способ, которым он работает, заключается в том, что крипто-процедуры имеют тенденцию хешировать число, так что, если один бит изменяется, каждый бит в равной степени может измениться в результате.
Рассмотрим простой модульный генератор (аналогичный некоторым реализациям в C rand())
int rand() { return seed = seed * m + a; }
если m = 0 и a = 0, это паршивый генератор с периодом 1: 0, 0, 0, 0,.... если m = 1 и a = 1, это также не очень случайный вид: 0, 1, 2, 3, 4, 5, 6,...
Но если вы выберете m и a для простых чисел около 2 ^ 16, это скажется вокруг красиво выглядящего очень случайного, если вы случайно осмотрите его. Но поскольку оба числа нечетны, вы увидите, что низкий бит будет переключаться, т.е. Число будет чересчур нечетным и четным. Не большой генератор случайных чисел. И так как в 32-битном номере есть только 2 ^ 32 значения, по определению после 2 ^ 32 итераций, вы повторите последовательность снова, сделав очевидным, что генератор НЕ случайный.
Если вы думаете о средних битах как о хорошем и скремблированном, в то время как нижние не так случайны, то вы можете построить лучший генератор случайных чисел из нескольких из них, с различными битами XORed вместе, чтобы все бит хорошо покрыт. Что-то вроде:
(rand1() → 8) ^ rand2() ^ (rand3() > 5)...
Тем не менее, каждое число переключается синхронно, что делает это предсказуемым. И если вы получите два последовательных значения, они скоррелированы, так что, если вы их построите, вы получите строки на экране. Теперь представьте, что у вас есть правила, объединяющие генераторы, так что последовательные значения не являются следующими. Например
v1 = rand1() → 8 ^ rand2()... v2 = rand2() → 8 ^ rand5()..
и представьте, что семена не всегда продвигаются вперед. Теперь вы начинаете делать что-то гораздо более трудное для прогнозирования на основе обратной инженерии, и последовательность длиннее.
Например, если вы каждый раз вычисляете rand1(), но только продвигаете семя в rand2() каждый третий раз, генератор, объединяющий их, может не повторяться намного дольше, чем период одного из них.
Теперь представьте, что вы накачиваете свой (довольно предсказуемый) генератор случайных чисел по модулю типа через DES или какой-либо другой алгоритм шифрования. Это скопирует бит.
Очевидно, что есть лучшие алгоритмы, но это дает вам представление. В Numerical Recipes реализовано множество алгоритмов, реализованных в коде и объясненных. Один очень хороший трюк: генерировать не один, а блок случайных значений в таблице. Затем используйте независимый генератор случайных чисел для выбора одного из сгенерированных чисел, сгенерируйте новый и замените его. Это нарушает любую корреляцию между соседними парами чисел.
Третья категория - это фактические аппаратные генераторы случайных чисел, например, основанные на атмосферном шуме
http://www.random.org/randomness/
Это, согласно современной науке, действительно случайное. Возможно, когда-нибудь мы обнаружим, что оно подчиняется некоторому основному правилу, но в настоящее время мы не можем предсказать эти значения, и они "по-настоящему" случайны, насколько нам известно.
Библиотека boost имеет отличные С++-реализации генераторов Фибоначчи, действующих царей псевдослучайных последовательностей, если вы хотите увидеть некоторый исходный код.
Я просто добавлю ответ на первую часть вопроса (часть "может?" ).h
Компьютеры могут генерировать (ну, генерировать, возможно, не совсем точное слово) случайные числа (как в, а не псевдослучайные). В частности, используя случайную случайность, получаемую через специализированные аппаратные устройства (которые генерируют случайность, основанную на шуме, например, например), или используя экологические входы (например, тайминги жесткого диска, тайм-ауты ввода пользователя).
Однако это не влияет на второй вопрос (как это работает Random.Next()
).
Класс Random
представляет собой генератор псевдослучайных чисел.
Это в основном чрезвычайно длинная, но детерминированная повторяющаяся последовательность. "Случайность" происходит от начала в разных положениях. Указание того, с чего начать, выполняется путем выбора seed для генератора случайных чисел и может быть, например, сделана с использованием системного времени или путем получения случайное семя из другого случайного источника. конструктор случайных событий по умолчанию использует системное время в качестве семени.
Фактический алгоритм, используемый для генерации последовательности чисел, описан в MSDN:
Текущая реализация класса Random основана на алгоритме генератора случайных чисел Дональда Э. Кнута. Для получения дополнительной информации см. D. E. Knuth. "Искусство программирования, том 2: Семинумерные алгоритмы". Addison-Wesley, Reading, MA, второе издание, 1981.
Компьютеры используют генераторы псевдослучайных чисел. По сути, они работают, начиная с номера семени и повторяя его с помощью алгоритма каждый раз, когда требуется новое псевдослучайное число.
Процесс, конечно, полностью детерминирован, поэтому заданное семя будет генерировать точно такую же последовательность чисел каждый раз, когда оно используется, но генерируемые числа образуют статистически однородное распределение (приблизительно), и это прекрасно, поскольку в большинстве случаев все, что вам нужно, это случайная случайность.
Обычная практика заключается в том, чтобы использовать текущее системное время как семя, но если требуется больше безопасности, "энтропия" может быть собрана из физического источника, такого как задержка на диске, чтобы генерировать семя, которое сложнее предсказать, В этом случае вы также захотите использовать криптографически сильный генератор случайных чисел например это.
Я не знаю много деталей, но я знаю, что семя используется для генерации случайных чисел, а затем основано на некотором алгоритме, который использует это семя, чтобы получить новое число.
Если вы получаете случайные числа, основанные на одном семени, они будут одинаковыми.