БлогNot. Генерация случайных чисел на PHP

Генерация случайных чисел на PHP

На стареньком уже PHP 4.3.1 большую часть дня писал скрипт. В коде имелись 2 функции, назначение которых - генерация случайных чисел в заданных диапазонах.

Вот начальный код:

function select_random_items ($k,$arr) { //выбрать $k случайных элементов из массива $arr
  $c=count($arr);
  if ($k>$c) $k=$c;
  if ($k==$c) return $arr;
  $a = array ();
  //Начиная с PHP 4.2.0 эта строка будет только мешать! srand (time());
  for ($i=0; $i<$k; ) {
   $n=rand (0,$c-1);
   if (!in_array($arr[$n],$a)) {
    array_push ($a,$arr[$n]); $i++;
   }
  }
  return $a;
 }

 function random_numbers ($kol,$all) { //вернет массив из $kol случ. чисел в диапазоне [0,$all-1]
  if ($kol>$all) $kol=$all;
  $a = array ();
  //Начиная с PHP 4.2.0 эта строка будет только мешать! srand (time());
  for ($i=0; $i<$kol; ) {
   $n=rand (0,$all-1);
   if (!in_array($n,$a)) {
    array_push ($a,$n); $i++;
   }
  }
  return $a;
 }

Обратите внимание на закомментаренную строку, "которая будет только мешать".

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

В свою очередь, обе эти функции вызывались в цикле, чтоб сформировать некий массив номеров.

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

После пары часов тестирования в разных режимах ответ нашелся в доке по PHP: srand: Since PHP 4.2.0 it's no longer necessary to seed the random number generator before using it. (начиная с версии PHP 4.2.0 больше нет необходимости вызывать эту функцию).

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

С другой стороны, скрипт может понадобиться запускать и в более старых версиях PHP. Универсальный выход - делать вызов srand или ее аналога mt_srand из кода, выполняемого только единожды при старте системы, например, так:

<?php
 session_start();
 if (!isset($_SESSION['random_init'])) {
  //Инициализировать генератор с.ч. только 1 раз!
  //С версии PHP 4.2.0 инициализация может только мешать генерации нормальных цепочек!
  mt_srand( (double) microtime() * 1000000);
  $_SESSION['random_init']='1';
 }
?>

 Оригинал статьи

17.12.2008, 13:11 [15697 просмотров]


теги: программирование random php

К этой статье пока нет комментариев, Ваш будет первым