2014-10-07 2 views
-1

Наконец-то я смог создать способ воспроизвести ошибку, которую у меня есть. Когда 2 или более пользователей вызывают страницу с той же второй функцией modsecurity, генерирует ту же последовательность случайных чисел (используя функцию rand() из php) для обоих пользователей.серьезная ошибка со случайными номерами

Вот демонстрация ошибки:

http://quemfazsite.com.br/em_criacao/modelo9/teste.php

Открытие эту страницу, 2 фреймов будет загружать и каждый из них должен быть генерации случайных чисел independetly друг от друга, но оба кадра генерируют ту же последовательность случайные числа! Очень простой исходный код можно увидеть ниже. Если вы не видите одну и ту же последовательность, я прошу вас перезагрузить страницу несколько раз, пока вы не получите такую ​​же последовательность чисел.

EDIT: эта ошибка происходит только при активной активности. Если вы прокомментируете строку «LoadModule», загружающую modsecurity, ошибка не будет!

<?php 

if (isset($_GET["test"])) { 

     $output= ""; 

     for ($i=0;$i<10;$i++) { 

       $output.= rand(0,99999999) . "<br />"; 

     } 

     echo $output; 

     exit(); 

} 

?> 
<iframe src="PUT_THE_SAME_NAME_OF_THIS_FILE_HERE.php?test&953487"></iframe> 
<iframe src="PUT_THE_SAME_NAME_OF_THIS_FILE_HERE.php?test&234322"></iframe> 
+0

Используйте mt_rand() вместо rand(), но ни один из них не производит случайное число, которое можно считать криптографически безопасным .... обратите внимание также, что если вы сольете случайное число, тогда две последовательности, начинающиеся с одной и той же соли, всегда будут одинаковыми –

+1

Ваш вопрос не имеет ничего общего с модулем modsecurity или apache. Я удалил соответствующие теги. – GhostGambler

+1

Рекомендуемое чтение: http://en.wikipedia.org/wiki/Random_number_generation – Sammitch

ответ

2

rand не предназначен для производства случайных чисел. Его целью является создание pseudorandom numbers, которые распределяются равномерно между заданными конечными точками. Если вы создадите гистограмму чисел, которые вы создали, вы увидите, что они действительно равномерно распределены.

Алгоритм, который генерирует эти числа, полностью детерминирован. Если вы предоставите одно и то же семя (обычно на основе текущего времени, как в вашем примере), вы получите точно такую ​​же последовательность чисел. Это особенность, а не ошибка: она позволяет использовать статистические свойства дистрибутива, а затем воспроизводить результаты после повторного использования семени.

Если вам нужны непредсказуемые случайные числа, вы должны использовать cryptographic RNG.

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

+0

Привет, спасибо, и вы правы, я согласен, но есть проблема: rand() не использует причину времени, если вы зацикливаете for (i = 0; i <1000; i ++) echo rand(); вы увидите, что все случайные числа будут разными, несмотря на то, что они были созданы почти в одно и то же время. На другом rand, если другой человек выполняет тот же скрипт примерно в то же время, что и первый, они будут генерировать одну и ту же случайную последовательность. Я обнаружил, что если разница между двумя пользователями составляет менее 1 секунды, тогда последовательность будет точно такой же ТОЛЬКО, если и ТОЛЬКО ЕСЛИ modsecurity включен. Итак, я верю, что вы говорите, неточно – Amanda

+1

@ Аманда 'rand' засевается текущим временем ** при первом вызове ** - он затем сохраняет состояние для последующих вызовов. После того, как вы засеете генератор псевдослучайных чисел, последовательность чисел, которые он будет генерировать, определяется однозначно. Опять же, это поведение ** ожидается **. Я еще раз хочу подчеркнуть, что если вам нужны уникальные номера, вы не должны использовать 'rand' в первую очередь; по крайней мере, используйте некоторый алгоритм хеширования с низкой достаточной скоростью столкновения на основе текущей микросекунды (например, 'sha1' с' microtime'). (Но будьте осторожны, что столкновения ** могут все еще возникать). –

+0

@Amanda Что касается 'mod_security', я не знаю, как это работает, но разница в поведении, которую вы наблюдаете, просто связана с тем, как« rand »засеяли и ничего больше. Так как 'rand' - плохая функция, вы должны смотреть на альтернативы. Я предлагаю вам прочитать генерацию случайных чисел (псевдо), прежде чем использовать их так. –

Смежные вопросы