2016-01-11 12 views
5

Voglio creare un programma che richiede solo un numero casuale, quindi cerco di usare l'indirizzo di argc nella funzione principale come sorgente casuale perché penso che la posizione del programma in memoria sia casuale, e inoltre possa salvare alcuni di essi dichiarazioni, quindi ho provato:Posso usare l'indirizzo di argc in main come sorgente casuale?

#include <stdio.h> 
int main(int argc,const char* argv[]){ 
    printf("%lu\n",(unsigned long int)&argv/sizeof(unsigned long int)); 
    return 0; 
} 

ma ho trovato l'uscita in ogni tempo non è molto "random": sono multipli di 4:

17591828907268 
17591841542404 
17591845040388 
17591834556676 

Qual è la ragione? E sta usando l'indirizzo di argc come numero casuale possibile?

poi cerco rimuovere alcuni bit dell'indirizzo:

#include <stdio.h> 
int main(int argc,const char* argv[]){ 
    printf("%lu\n",(unsigned long int)&argv >> 12); 
    return 0; 
} 

sembra abbastanza casuale questa volta, almeno ha sia numeri pari e dispari:

34359070631 
34359034616 
34359078055 
34359080624 

è che "corretto" modo per trasformare l'indirizzo di argc in un numero casuale?

+0

Stai chiedendo se '& argc' è un buon seme da usare per' srand() '? –

+0

È improbabile che la posizione del programma in memoria sia casuale. Il sistema operativo utilizza un algoritmo per determinare la posizione in memoria del programma e quell'algoritmo riflette una strategia scelta dal sistema operativo. – Dko

+0

Non esiste realmente un "numero casuale". Ci sono sequenze casuali di numeri. Se è necessario un solo numero per ogni esecuzione del programma, è necessario sceglierlo da una sequenza generata al di fuori del programma. La proposta di John Hascall di/dev/random è una scelta eccellente. Qualcosa come random.com è un altro. –

risposta

3

Qual è il motivo?

Alignment requirements per la propria architettura, che presumo sia x86 e int è di 4 byte, il che significa ogni int dovrebbe essere allineato con un indirizzo che è divisibile per 4 (che è esattamente il comportamento che stai vedendo).

E sta utilizzando l'indirizzo di argc come numero casuale possibile?

Possibile? Yeah, sure. Vai avanti e fallo.

È una buona idea? No, decisamente no. Vedi sotto per il perché.

È il modo "corretto" per trasformare l'indirizzo di argc in un numero casuale?

Suppongo che per "corretto" intendi una buona fonte di entropia e la risposta è no.

C'è un certo grado di address space layout randomization nei sistemi operativi moderni, ma non è pensato per essere una buona fonte di entropia. Ha solo lo scopo di rendere più difficile per qualcuno utilizzare un bug nel tuo programma come un exploit di sicurezza. E non ci sono garanzie sull'ASLR (puoi spegnerlo in alcuni sistemi operativi se lo volessi).

In breve, non utilizzare l'indirizzo di una variabile come origine per l'entropia. Non è solo una buona fonte di casualità.

0

Sono multipli di 4 perché gli indirizzi di funzione saranno allineati alle parole su ogni piattaforma che conosco (presumo che sia x86 o x86_64?)

L'indirizzo di argc può essere "casuale" per un certo senso della parola, nel senso che probabilmente non si sa di cosa si tratta, quindi se lo si utilizza per seminare le condizioni di partenza per un gioco o qualsiasi altra cosa probabilmente funzionerebbe; Sicuramente non fare affidamento su di esso se stai usando questo per crypto o altro - un utente malintenzionato potrebbe fare cose per influenzare il punto in cui viene caricato argc.

Detto questo, la libreria C è dotata di funzioni perfettamente funzionanti rand() e srand() che, come bonus, consentono di seminarlo deliberatamente con un valore specifico che può essere molto utile nel debugging; Continuo con quello ogni volta che ho bisogno di numeri casuali, personalmente.

Problemi correlati