Creare un numero pseudocasuale: prima o poi capita a tutti. Ogni linguaggio di programmazione ha, nelle proprie librerie standard, dei metodi per generare numeri pseudocasuali, partendo da un seed, da un seme che alimenta l’algoritmo stesso.
La bontà della serie generata, dipende esclusivamente da questo seme. Non ci credete? Fate questo esperimento:
r1 ed r2 sono due oggetti slegati tra di loro, se si esclude il fatto che è stato passato lo stesso seed durante l’inizializzazione del motore di generazione di numeri pseudocasuali. Io scommetto che r1 ed r2 hanno generato lo stesso numero. Non solo, io scommetto che tutta la sequenza di numeri generati da r1 ed r2 sarà la stessa, per quanti tentativi voi facciate.
Primo risultato quindi: il seed influenza la sequenza pseudocasuale. Due generatori diversi, aventi lo stesso seed, genereranno la stessa sequenza pseudocasuale.
Il nocciolo del problema, quindi è: come scelgo questo seed?
Prendiamo l’esempio di prima e togliamo il parametro al costruttore della classe Random. In questo caso, come da documentazione, Random prende come seed dei valori dell’ambiente tra cui il PID del processo e alcuni bit di entropia presi da sorgenti dipendenti dal Sistema Operativo (/dev/urandom, ad esempio, nel caso dei sistemi Unix).
If number is omitted, seeds the generator using a source of entropy provided by the operating system, if available (/dev/urandom on Unix systems or the RSA cryptographic provider on Windows), which is then combined with the time, the process id, and a sequence number.
Una possibile soluzione, è quella di affidarsi al tempo per inizializzare il seed.
In questo caso però la scelta è peggiorativa, in quanto il seed è nettamente più piccolo come dimensioni.
Per complicare un po’ le cose, Ruby mette a disposizione anche la libreria securerandom. Lo scopo sembra, dalla documentazione, quello di generare alfanumerici pseudocasuali, ad esempio per la generazione di cookie di sessione o di password onetime.
Allora, usare securerandom è la scelta da fare quando serve generare una stringa pseudocasuale, quindi in ambito web, dovrà essere usata questa.
Se vi serve invece generare degli interi, la scelta deve ricadere su Random lasciando al Kernel dell’interprete di Ruby il compito di inizializzare il motore di generazione di numeri pseudocasuali.
Enjoy it!