Автор Тема: Случайни числа в PHP, какви алгоритми ползвате?  (Прочетена 2037 пъти)

xkernell

  • Напреднали
  • *****
  • Публикации: 46
  • Distribution: kubuntu 12.10, ubuntu 12.10
  • Window Manager: KDE, GNOME
    • Профил
Здравейте, до сега не ми се случвало да използвам генератори на случайни числа в PHP. В .NET има един клас System.Random от който съм много доволен, но когато се наложи да ползвам PHP попаднах на Rand(), който пък беше много зле, защото при малък диапазон от числа (0, 10) в над 50% от случаите получавам еднакво число 2-3 пъти подред. Та въпроса ми е какви алгоритми можете да ми предложите за по-случайни числа в диапазона (0, 50) защото най-често ще ми трябва да генерирам такива числа? То ясно, че напълно случайно няма как да стане, но предполагам, че доста хора от този форум са се сблъсквали с този проблем и са стигнали до някой отговори. :)
Активен

Odido

  • Напреднали
  • *****
  • Публикации: 627
  • Distribution: Arch Linux
  • Window Manager: Gnome
    • Профил
 Пробвай mt_rand.За не го пише, че е малко по-добър.
Активен

"Congratulations, you broke the Internet
Look at what you did! Are you happy now?"

Mitaka

  • Гост
function randomDigits($length){
    $numbers = range(0,9);
    shuffle($numbers);
    for($i = 0;$i < $length;$i++)
       $digits .= $numbers[$i];
    return $digits;
}

Източник:
http://stackoverflow.com/questions/3140235/php-random-number
Активен

dark_elf

  • Напреднали
  • *****
  • Публикации: 120
    • Профил
mt_rand е доста добро решение, но ако искаш да намалиш процента на повторение на числата запазвай последният резултат в една променлива. При поредното извикване на функцията за генериране на число, проверявай дали числото което се генерира в момента и предходното не са равни. Ако са равни генерираш ново, ако не са връщаш новото число.

Активен

Oxy

  • Напреднали
  • *****
  • Публикации: 253
  • Distribution: Fedora / Gentoo / Debian
  • Window Manager: KDE (4.2/ 3.5)
    • Профил
    • WWW
Ако искаш наистина случайни числа напиши си един тъп текст на ангийски:
$text="mystupidtextblablabla"; //трябва да е по-дълъг..
$numer1 = md5($text);
$number2 = md5(getTextFromPairOfSites()); //Вземаш целия хтмл текст на някъв сайт (примерно 10 сайта които се обновяват често в масив и после избора с този тъпия клас)
$case = randNumber();(1-4 от някъв генератор пак)
$myRandom;
if ($case == 1) {
 $myRandom = ($numer1 + $number2) % $maxNumer; // Ето ти число между и $maxNumber
}
else if($case ==2){
 $myRandom = ($numer1 * $number2) % $maxNumer; // Ето ти число между и $maxNumber
}
......
и така за четирите основни операции...

предполагам че целия генератор в ПХП е някакъв линеарен конгруентен генератор.. Аз такава тъпня не бих ползвал за хай сек неща... ама аз и ПХП не бих ползвал...

gat3way

  • Напреднали
  • *****
  • Публикации: 6050
  • Relentless troll
    • Профил
    • WWW
С каква цел генерираш случайни числа?
Активен

"Knowledge is power" - France is Bacon

xkernell

  • Напреднали
  • *****
  • Публикации: 46
  • Distribution: kubuntu 12.10, ubuntu 12.10
  • Window Manager: KDE, GNOME
    • Профил
Ами работя по един личен проект. Малко е сложно за обяснение, трябва едни медийни файлове да се избират на случаен принцип. Не ми трябва да е нещо адски добро, просто да не съвсем зле.

За сега реших да генерирам десет числа с mt_rand() като ги следя дали са еднакви и от там да избирам пак с mt_rand() едно от тях. Не съм сигурен дали е най-производителното решение, но това ми е добре за сега. :)
Активен

romeo_ninov

  • Напреднали
  • *****
  • Публикации: 2155
    • Профил
Ами работя по един личен проект. Малко е сложно за обяснение, трябва едни медийни файлове да се избират на случаен принцип. Не ми трябва да е нещо адски добро, просто да не съвсем зле.

За сега реших да генерирам десет числа с mt_rand() като ги следя дали са еднакви и от там да избирам пак с mt_rand() едно от тях. Не съм сигурен дали е най-производителното решение, но това ми е добре за сега. :)
а защо не вземеш да четеш от /dev/urandom?
Активен

0x2B|~0x2B

gat3way

  • Напреднали
  • *****
  • Публикации: 6050
  • Relentless troll
    • Профил
    • WWW
Щом не е за каквито и да било security цели (примерно генериране на random token-и, сесийни ID-та, линкове за ресет-ване на парола и т.н.), mt_rand() върши добра работа. Обикновената rand() функция наистина е LCG и както си забелязал има доста ясно изявен bias. Особено като вземеш резултатите mod някаква ниска стойност, тогава доста си личи :)

Ако е за security нужди и няма нужда кода да работи върху нещо различно от linux, четенето от /dev/urandom е ОК.

А иначе с mt_rand(), първоначалното seed-ване е най-скъпата операция, генерирането на последващите числа е доста по-евтино.
Активен

"Knowledge is power" - France is Bacon