Как я могу генерировать действительно (не псевдо) случайные числа с C #? - PullRequest
29 голосов
/ 05 августа 2009

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

Ответы [ 12 ]

1 голос
/ 05 августа 2009

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

Тем не менее, если у вас нет доступа к такому источнику действительно случайных чисел, вы могли бы использовать процесс «бедняка», подобный этому:

  • Создать длинный массив (10000 или более элементов?) Чисел
  • Заполните массив текущими случайными числами, посеянными во времени, стандартным способом
  • Когда требуется случайное число, сгенерировать случайный индекс в массиве и вернуть число, содержащееся в этой позиции
  • Создать новое текущее случайное число с временным номером в индексе массива, чтобы заменить используемое число

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

Вот пример библиотеки, которая реализует описанный выше алгоритм на C ++: http://www.boost.org/doc/libs/1_39_0/libs/random/random-generators.html

0 голосов
/ 22 сентября 2016

Просто уточнить, что все, кто говорит, что в C # или на вашем компьютере нет True RNG, ошибаются. Многоядерный процессор по своей сути является Истинным ГСЧ. Очень просто, используя преимущества вращения процессора, вы можете генерировать були, которые не имеют заметного паттерна. Оттуда вы можете генерировать любой диапазон чисел, который вы хотите, используя bool в качестве битов и создавая число путем сложения битов.

Да, это величины медленнее, чем чисто математическое решение, но чисто математическое решение всегда будет иметь образец.

public static bool GenerateBoolean()
{
    var gen1 = 0;
    var gen2 = 0;
    Task.Run(() =>
    {
        while (gen1 < 1 || gen2 < 1)
            Interlocked.Increment(ref gen1);
    });
    while (gen1 < 1 || gen2 < 1)
        Interlocked.Increment(ref gen2);
    return (gen1 + gen2) % 2 == 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...