Corsi on-line

Il random() di PHP è taroccato?

La funzione random (presente, con vari nomi, in quasi tutti i linguaggi di programmazione) genera un numero casuale, anzi pseudo-casuale, utilizzando un algoritmo matematico e partendo da una radice detta “seme”.
Agli albori dell’informatica moderna (penso alle prime versioni di linguaggi com Basic, Fortran e Pascal) nei vari manuali si leggeva di fare attenzione all’utilizzo di tale funzione (o meglio “parola chiave”) in quanto i valori restituiti non sempre potevano considerarsi casuali.

Ora, se il valore restituito non fosse proprio casuale poca importanza avrebbe qualora tale risultato venisse utilizzato per presentare un banner diverso ad ogni apertura di una pagina… certamente diverso sarebbe il discorso qualora si stesse utilizzando questa funzione per gestire una lotteria o una partita di poker on-line! Individuando la meccanica di restituzione dei valori, infatti, si potrebbe alterare la validità di concorsi e giochi ottenendone un ingiusto vantaggio economico.

Mi è venuta la curiosità, quindi, di verificare se la funzione random() di PHP debba considerarsi “taroccata” oppure no, cioè se i valori che restituisce siano effettivamente casuali o meno. Allo scopo mi sono fatto questo piccolo script.

<?php
// ATTENZIONE: ($max - $min) + 1 deve essere minore o uguale a 20
$min=1; //valore minimo
$max=6; //valore massimo
/*
esempi:
con $min=0 e $max=1 simulo lancio di una moneta (testa o croce)
con $min=1 e $max=6 simulo il lancio di un dado
ecc....
*/
$prove=10000; //deve essere maggiore di ($max - $min) + 1
//*** non modificare le righe che seguono ***
$conta=array();
$chi2=0;
$chTeo=array(3.841, 5.991, 7.815, 9.488, 11.07, 12.59, 14.07, 15.51, 16.92, 18.31, 19.68, 21.03, 22.36, 23.68, 25, 26.30, 27.59, 28.87, 30.14);
for($k=0;$k<$prove;$k++){
   $estr=rand($min,$max);
   $conta[$estr]++;
}
$teorica=$prove/count($conta);
$gradi_lib=count($conta)-1;
for($j=$min;$j&lt;=$max;$j++){
  $delta=$conta[$j]-$teorica;
  $chi2 +=pow($delta,2)/$teorica;
  echo &quot;il numero $j è stato estratto &quot;.$conta[$j].&quot; volte<br>";
}
echo "<br>fatte ".number_format($prove,0,',','.')." di estrazioni di ".count($conta)." numeri compresi tra $min e $max<br>";
echo "valore chi quadro calcolato = ".number_format($chi2,2,',','.')."<br>";
echo "valore chi quadro teorico (per $gradi_lib gl al 95%) = ".number_format($chTeo[$gradi_lib-1],2,',','.')."<br>";
if ($chi2 < $chTeo[$gradi_lib-1]){
 echo "<br>la funzione random() non è taroccata";
}else{
 echo "<br>la funzione random() è taroccata, meglio non giocare";
}
?>

Ebbene, dopo varie prove devo dire che gli algoritmi per l’estrazione dei numeri casuali, almeno quello per PHP, sono notevolmente migliorati rispetto ad un tempo!

Post correlati
  • nicola

    Potresti spiegare perchè, in base a cosa lo deduci, com’era prima e cosa è cambiato adesso? altrimenti scusa, ma che articolo è questo?

  • Per prima cosa l’articolo è una semplice curiosità poi non so se nello spazio per i commenti riesco a spiegarti.
    Per prima cosa quello che dovrebbe metterti sull’avviso è che i numeri sono definiti pseudocasuali.
    Comunque affinchè una serie di numeri sia definito casuale è che la probabilità di estrarre un numero sia uguale a quello di estrane un altro. Quindi, data una serie di estrazioni la distribuzione delle frequenze deve risultare una distribuzione rettangolare.
    Per verificare, ad un determinato livello di significatività, se la distribuzione delle frequenze è rettangolare si può utilizzare il test del chiquadro.
    Ora i numeri pseudocasuali sono generati da un algoritmo matematico quindi, in funzione dell’algoritmo, la loro frequenza di estrazione dipende dall’algoritmo con cui vengono generati.
    Ti faccio in esempio.
    Data una moneta perfetta la probabilità che venga testa è 0.5 uguale a quella che venga croce (o se vuoi che venga 0 o 1).
    Se eseguo una serie di lanci e ottendo 109 teste e 91 croci posso affermare che la moneta è assimilabile ad una moneta perfetta. Ma se nella serie ottengo 10 teste e 190 croci devo respingere l’ipotesi che la moneta sia perfetta, per la verifica applico il suddetto test del chequadro.
    Nei primi anni 70, ad esempio, gli algoritmi cche si trovavano nel basic, non sempre erano rettangolari (spesso le frequenze di numeri della testa e della coda erano più basse) e il solito test non sempre faceva rientrare tali frequenze in una distribuzione rettangolare, qundi l’ipotesi che i numeri fossero casuali andava rifiutata.
    Le prove che ho fatto applicando detto test alla funzione php rand() al contrario, per ora, non ha mi ha fatto mai rifiutare l’ipotesi della casualità. Per cui si deduce che gli algoritmi sono migliorati.

I più letti del mese
Tematiche