Вопрос

Я знаю, что просто используя rand() предсказуемо, если вы знаете, что делаете, и имеете доступ к серверу.

У меня есть проект, который высоко зависит от выбора случайного числа, которое является настолько непредсказуемым, насколько это возможно.Поэтому я ищу предложения, либо другие встроенные функции, либо пользовательские функции, которые могут генерировать лучше случайное число.

Я использовал это, чтобы провести небольшой тест:

$i = 0;

while($i < 10000){
    $rand = rand(0, 100);

    if(!isset($array[$rand])){
        $array[$rand] = 1;
    } else {
        $array[$rand]++;
    }

    sort($array);
    $i++;
}

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

Это было полезно?

Решение

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

Вы правы насчет функции PHP rand().Смотрите второй рисунок на Статистический анализ за яркую иллюстрацию.(Первая цифра поражает, но она была нарисована Скоттом Адамсом, а не построена с помощью rand()).

Одним из решений является использование истинного генератора случайных чисел, такого как случайный.орг.Другой, если вы используете Linux/BSD/и т.д.это использовать /dev/случайный.Если случайность критически важна, вам придется использовать аппаратный генератор случайных чисел.

Другие советы

случайный.орг имеет API, к которому можно получить доступ через HTTP.

Random.org - это истинная служба случайных чисел, которая генерирует случайность посредством атмосферного шума.

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

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

Fourmilab также предлагает тестовая программа для проверки случайности.Вы можете использовать его для проверки различных программ myRand().

Что касается вашей последней программы, если вы генерируете 10 000 значений, почему бы вам не выбрать окончательное значение среди 10 тысяч?Вы ограничиваете себя подмножеством.Кроме того, это не будет работать, если ваши $min и $max больше 10000.

В любом случае, нужная вам случайность зависит от вашего приложения.rand() подойдет для онлайн-игры, но не подойдет для криптографии (все, что не проверено тщательно статистическими программами, в любом случае не подойдет для криптографии).Ты будешь судьей!

Вариация @KG, использующая миллисекунды с момента EPOCH в качестве начального числа для rand?

Другой способ получения случайных чисел, по своей сути схожий с получением UUID.

PHP версии 5.3 и выше

openssl_random_pseudo_bytes(...)

Или вы можете попробовать следующее библиотека используя RFC4122

новый PHP7 есть функция, которая делает именно то, что вам нужно:он генерирует криптографически безопасные псевдослучайные целые числа.

int random_int ( int $min , int $max )

Генерирует криптографические случайные целые числа, которые подходят для использования, где непредвзятые результаты имеют решающее значение (т.е.перетасовка колоды в покере).

Для более подробного объяснения PRNG и CSPRNG (и их разницы), а также того, почему ваш первоначальный подход на самом деле является плохой идеей, прочтите мою статью. еще один очень похожий ответ.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top