Losowa liczba w zakresie [min - max] przy użyciu PHP

84

Czy istnieje sposób na wygenerowanie liczby losowej na podstawie wartości minimalnej i maksymalnej?

Na przykład, jeśli min wynosi 1, a maksimum 20, powinno wygenerować dowolną liczbę od 1 do 20, w tym 1 do 20?

Val
źródło
1
Nowa wersja php posiada bezpieczny kryptograficznie generator liczb losowych .
Salvador Dali,
1
PHP 7+ użytku random_int(), random_bytes()lub openssl_random_pseudo_bytes() . jak powiedział @Salvador Dali rand(), nie generują wyników bezpiecznych kryptograficznie. Zobacz dokumentację php.net/manual/en/function.rand.php
FrozenFire

Odpowiedzi:

147
<?php
  $min=1;
  $max=20;
  echo rand($min,$max);
?>
Więzień
źródło
myślałem, że min i max dla rand to liczba cyfr do użycia zamiast liczb :) thnx
Val
Powiązane: jeśli PHP_INT_MAX < ($max-$min)musisz dodać interwały razem, jak opisano w tej odpowiedzi .
biskup
rand () przed PHP7.1 jest po prostu zły. Wykorzystuje algorytm LCG, który daje przewidywalne wyniki. Jest również powolny. Od PHP7.1 rand () jest aliasem mt_rand (), więc nie jest już zły. PHP7 wprowadziło również bezpieczne kryptograficznie random_int (), jednak należy tego unikać, chyba że jest to konieczne, ponieważ jest znacznie wolniejsze niż mt_rand ()
xZero
34

W nowym PHP7 jest wreszcie wsparcie dla kryptograficznie zabezpieczonych pseudolosowych liczb całkowitych.

int random_int ( int $min , int $max )

random_int - generuje bezpieczne kryptograficznie pseudolosowe liczby całkowite

co zasadniczo sprawia, że ​​poprzednie odpowiedzi są nieaktualne.

Salvador Dali
źródło
2
To wspaniale! Ale dopóki hostingi nie obsługują PHP7 bardziej globalnie, niestety nie jest to przydatne dla nikogo, kto tworzy produkty do dystrybucji. Tak więc poprzednie odpowiedzi, które TAKŻE działają na PHP7, są nadal najlepszą praktyką.
Matt Cromwell
1
@MattCromwell. Nie zgadzam się z wami. Dopóki usługi hostingowe nie obsługują PHP7, powinniśmy używać polyfill dla random_inti random_bytesfunkcji - github.com/paragonie/random_compat .
Vladimir Posvistelik
Jestem ciekawy, czy jest kiedykolwiek powód, aby NIE używać random_int ? Jeśli daje „lepsze” liczby losowe, dlaczego nie użyć go z powodów innych niż krypto?
Brian Leishman,
1
@BrianLeishman Wolałbym używać go do wszystkiego. Jedyny minus, jaki mogę się domyślić: prawdopodobnie opiera się na źródle losowości i może zawieść, jeśli nie jesteś losowy. Może być drożej (trzeba to sprawdzić), ale wątpię, czy ta jedna funkcja robi dużą różnicę
Salvador Dali
Wiem, że jest wolniejszy, ale na tyle nieistotny, aby nie cofać się i nie zmieniać już istniejących random_ints na rands. Ponadto moim przypadkiem użycia jest algorytm ponawiania i zdecydowanie nie chcę, aby wiele nieudanych funkcji zlepiało się po uśpieniu z powodu przewidywalnych losowych ints
Brian Leishman
19

Szybciej szybsza wersja użyłby mt_rand:

$min=1;
$max=20;
echo mt_rand($min,$max);

Źródło: http://www.php.net/manual/en/function.mt-rand.php .

UWAGA: Aby to działało, Twój serwer musi mieć włączony moduł Math PHP. Jeśli tak się nie stanie, zrób błąd swojego hosta, aby go włączyć, lub musisz użyć normalnego (i wolniejszego) rand ().

Matt Cromwell
źródło
6
masz na myśli szybciej, prawda? różnica jest taka (wpisując == szybciej vs szybciej == pod względem wydajności)
Val
polish.stackexchange.com/questions/31732/… - właściwie może być jedno i drugie
pee2pee
6

Tutaj zestawiłem odpowiedzi i uczyniłem je niezależnymi od wersji;

function generateRandom($min = 1, $max = 20) {
    if (function_exists('random_int')):
        return random_int($min, $max); // more secure
    elseif (function_exists('mt_rand')):
        return mt_rand($min, $max); // faster
    endif;
    return rand($min, $max); // old
}
vonUbisch
źródło
0

Spróbuj tego. Wygeneruje identyfikator zgodnie z Twoim życzeniem.

function id()
{
 // add limit
$id_length = 20;

// add any character / digit
$alfa = "abcdefghijklmnopqrstuvwxyz1234567890";
$token = "";
for($i = 1; $i < $id_length; $i ++) {

  // generate randomly within given character/digits
  @$token .= $alfa[rand(1, strlen($alfa))];

}    
return $token;
}
asi_x
źródło