Можно ли прогнозировать rand (0,10) в PHP? - программирование
Подтвердить что ты не робот

Можно ли прогнозировать rand (0,10) в PHP?

У меня есть script, где я использую функцию rand в PHP. Теперь я прочитал несколько рассказов о привидениях, которые позволяют легко предсказать эти результаты. Возможно ли это с клиентской стороны?

Например, допустим, что у нас есть rand(0,10). Можно ли предсказать следующий номер?

4b9b3361

Ответ 1

Функция

rand() возвращает псевдослучайное число. Это НЕ означает, что число next может быть предсказано. Однако это изображение может объяснить концепцию слова pseudorandom

rand

Вы можете прочитать эту статью

изображение создается из простого цикла с помощью функции rand в системе Windows.

header("Content-type: image/png");
$im = imagecreatetruecolor(512, 512) or die("Cannot Initialize new GD image stream");
$white = imagecolorallocate($im, 255, 255, 255);
for ($y = 0; $y < 512; $y++) {
    for ($x = 0; $x < 512; $x++) {
        if (rand(0, 1)) {
            imagesetpixel($im, $x, $y, $white); 
        } 
    } 
} 
imagepng($im); imagedestroy($im);

Это не так случайно, правда? Но теперь, когда вы это знаете... вы можете предсказать следующий номер?

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

[...]

Не так много PRNG создадут очевидный визуальный шаблон, подобный этому, так бывает, что это очень плохое сочетание языка (PHP), операционной системы (Windows) и функции (rand()).

Ответ 2

Вам нужно будет принудительно использовать состояние PRNG. http://crypto.di.uoa.gr/CRYPTO.SEC/Randomness_Attacks_files/paper.pdf

PHP rand() использует базовую реализацию стандартной библиотеки, это зависит от операционной системы.

Итак, первый шаг, определите операционную систему.

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

Для простоты предположим, что семя для PRNG - это что-то вроде миллисекундного времени сервера. Итак, HTTP-запрос приходит, PHP семенирует PRNG и выполняет rand (0,10). Если вы хотите предсказать, что вы...

  • Синхронизируйте ваши клиентские часы с сервером, статистически получая точное время от отправки HTTP-запроса на сервер и считывая HTTP-заголовок ответа с отметкой времени.

  • Поместите свой PRNG клиента (это такая же реализация, что и сервер) с прогнозируемым будущим временем, когда вы запросите rand (0,10) с сервера. Запустите rand (0,10) на клиенте, отправьте запрос в точное время на сервер, и результаты будут одинаковыми.

  • Время пинга, время обработки и т.д. делают этот подход довольно грубым.

Действительно, через Интернет (не имея прямого доступа к серверу) вам не удастся предсказать результаты функции PHP rand().

Ответ 3

Из rand manual:

Псевдо-случайное значение между min (или 0) и max (или getrandmax(), включительно).

Итак, случайный случай не случайный, а псевдослучайный. Если вы знаете, как выполняется caluclation, и знаете начальное значение, можно предсказать (вычислить) следующее значение.

Если вам нужно истинное случайное значение, вам нужен другой алгоритм. Например, на основе белого шума.

Ответ 4

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

Это означает, что можно вычислить число, если вы получили доступ к машине, но это все еще вряд ли произойдет. Конечный пользователь, который только что видит выход PHP и не имеет доступа к машине, не имеет возможности для вычисления или прогнозирования следующего значения. Вывод нескольких вызовов rand() внутри ONE выполнения php script может * технически * быть предсказуемым, но это нельзя использовать в любом случае, поскольку пользователь видит только вывод ONE WHOLE, не имея возможности взаимодействовать во время выполнения PHP script.

Это процедура, используемая для генерации семпла для PHP rand():

#ifdef PHP_WIN32
#define GENERATE_SEED() (((long) (time(0) * GetCurrentProcessId())) ^ ((long) (1000000.0 * php_combined_lcg(TSRMLS_C))))
#else
#define GENERATE_SEED() (((long) (time(0) * getpid())) ^ ((long) (1000000.0 * php_combined_lcg(TSRMLS_C))))
#endif

Начиная с PHP 4.2.0, The random number generator is seeded automatically.

Ответ 5

Я думаю, что вы можете провести различие между безопасным и безопасным. Ответ на ваш вопрос о предсказании "да", можно предсказать числа, генерируемые из генератора псевдослучайных чисел. Однако, я думаю, что более важным вопросом является то, насколько вероятно, что это произойдет. Что вы пытаетесь защитить от предсказания? Если вы используете массовый онлайн-игровой сайт, вероятно, более важно иметь истинную случайность, чем при запуске небольшого MUD-сервера. Это более важно, потому что последствия пользователя, нарушающего шаблон, более серьезны, и существует большая вероятность того, что у пользователя будет мотивация тратить время на атаку на ваш алгоритм.

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

http://www.random.org/clients/http/

Ответ 6

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

Почему?

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

  • строка многих чисел не будет действительно случайной
  • следующий номер (в следующем http-запросе) не может быть определен с клиентской стороны