2014-10-18 26 views
7

Ispirato da General purpose random number generation Ho deciso di eseguire i miei test per vedere cosa c'era di sbagliato in rand(). Usando questo programma:È davvero rand() così male?

srand(time(0)); 
for (int i = 0; i < 1000000; ++i) 
{ 
    std::cout << rand() % 1000 << " "; 
} 

ho caricato in ottava utilizzando i comandi:

S = load("test.txt") 
hist(S) 

e ottenuto questo risultato:

result

Per me i risultati sembrano essere piuttosto uniforme. Mi aspettavo che i risultati fossero più distorti. Ho condotto il mio test in modo sbagliato?

+2

rand è principalmente negativo perché: 'RAND_MAX' è definito dall'implementazione, e per esempio su Visual Studio è semplicemente 2^16; rand è globale, nel senso che se qualcun altro oltre a te chiama srand, potrebbe rovinare il tuo codice. Se hai compilatore C++ 11-compilant, considera l'utilizzo di uno dei suoi RNG – Creris

+0

A seconda dell'implementazione, 'rand()' può avere un'entropia bassa sui suoi bit più bassi. Se hai fatto 'rand()% 4', in alcune implementazioni questo è piuttosto non uniforme. Questo è il motivo per cui è generalmente raccomandato (se usi 'rand()') per scrivere 'rand()/(RAND_MAX/4)' in questo caso. – leemes

+6

* È davvero rand() così male? * SÌ! –

risposta

8

Il test nella tua domanda non verifica realmente la casualità. Tutto ciò che fa è assicurarsi che i numeri siano distribuiti uniformemente. Questa è una condizione necessaria ma non sufficiente: ci sono molti altri modi in cui un generatore di numeri casuali può essere carente.

Ad esempio, se fornissi una funzione che restituiva i numeri 0, 1, 2, ..., 999 in un ciclo, passerebbe anche il test. Eppure chiaramente fallirebbe qualsiasi ragionevole definizione di casualità.

Per vedere come casuale generatori di numeri vengono testati in pratica, dare un'occhiata a

Per una discussione di rand() specificamente, controlla rand() Considered Harmful .

+0

http://xkcd.com/221/ EDIT: Il dilbert sul tuo secondo link è ancora meglio. –

1

Un punto importante che non si sta valutando è quanto sia prevedibile la sequenza casuale generata. Quando si usa time() come seme della casualità, se l'attaccante conosce - più o meno - quando il seme è stato generato, può piuttosto facilmente riprodurre l'intera sequenza casuale.

Questo è il motivo per cui si desidera una vera fonte casuale, assumendo che si utilizzino questi numeri casuali per qualsiasi cosa relativa alla sicurezza.

Quando la sicurezza è davvero importante, si desidera inoltre ottenere ognuno dei propri numeri dalla vera fonte casuale, senza fare affidamento su un PRNG. Più lento ma più sicuro.

0

Dipende dallo scopo, l'rand() fornito è semplice da utilizzare con una distribuzione accettabile, non è progettato per scopi di crittografia, né scopo di simulazione fisica. Se si desidera un livello di crittografia o una simulazione fisica, non è una buona scelta e potrebbe essere necessario ottenere un'implementazione speciale.
non c'è reale casualità prodotta dai programmi per computer.

+1

Per quanto riguarda l'ultima frase, stai escludendo questi dispositivi: http://en.wikipedia.org/wiki/Hardware_random_number_generator? – NPE

+0

@NPE grazie per la cortese correzione. –

Problemi correlati