In che modo differiscono i numeri pseudocasuali e veramente casuali e perché è importante?


664

Non l'ho mai capito. Dì solo che scrivi un piccolo programma in qualsiasi lingua che tira dei dadi (usando solo i dadi come esempio). Dopo 600.000 lanci, ogni numero sarebbe stato ruotato circa 100.000 volte, che è quello che mi aspetto.

Perché ci sono siti Web dedicati alla "casualità reale"? Sicuramente, data l'osservazione di cui sopra, le probabilità di ottenere qualsiasi numero sono quasi esattamente 1 su quanti numeri può scegliere.

L'ho provato in Python : ecco il risultato di 60 milioni di rotoli. La variazione più alta è come 0,15. Non è così casuale come sta per arrivare?

1 - 9997653 2347.0
2 - 9997789 2211.0
3 - 9996853 3147.0
4 - 10006533 -6533.0
5 - 10002774 -2774.0
6 - 9998398 1602.0

1
Dai un'occhiata all'articolo di Wikipedia sui numeri casuali generati dall'hardware Vedi anche questo - stats.stackexchange.com/questions/32794/…
steadyfish

21
Cosa intendi con "tira un dado"? Ha un braccio robot e una videocamera collegati?
Starblue,

3
mentre sono d'accordo con l'essenza generale del tuo tono, che spesso ci preoccupiamo troppo di questo, ma è stato sfruttato nella vita reale: en.wikipedia.org/wiki/Ronald_Dale_Harris
Grady Player

3
Vedi questo articolo su un gioco di poker online privo di casualità reale per cui è importante.
Varaquilex,

1
Se mantieni un segnalino 0-5 e tira un dado di conseguenza, 666 gorillion volte, otterrai anche una distribuzione uguale.
jcora,

Risposte:


1383

Giochiamo a poker con il computer, solo tu, io e un server di cui entrambi ci fidiamo. Il server utilizza un generatore di numeri pseudo-casuale che viene inizializzato con un seme a 32 bit proprio prima di giocare. Quindi ci sono circa quattro miliardi di mazzi possibili.

Ho cinque carte in mano - apparentemente non stiamo giocando a Texas Hold 'Em. Supponiamo che le carte vengano distribuite una a me, una a te, una a me, una a te e così via. Quindi ho la prima, la terza, la quinta, la settima e la nona carta nel mazzo.

In precedenza ho eseguito il generatore di numeri pseudo-casuale quattro miliardi di volte, una volta per ogni seme, e ho scritto la prima carta generata per ciascuna in un database. Supponiamo che la mia prima carta sia la regina di picche. Ciò mostra solo una come prima carta in una su ogni 52 possibili mazzi, quindi abbiamo ridotto i mazzi possibili da quattro miliardi a circa 80 milioni circa.

Supponiamo che la mia seconda carta sia il tre di cuori. Ora eseguo il mio RNG 80 milioni di volte in più usando gli 80 milioni di semi che producono la regina di picche come primo numero. Mi ci vogliono un paio di secondi. Scrivo tutti i mazzi che producono i tre cuori come terza carta, la seconda carta nella mia mano. Questo è di nuovo solo circa il 2% dei deck, quindi ora siamo scesi a 2 milioni di deck.

Supponiamo che la terza carta nella mia mano sia il 7 di fiori. Ho un database di 2 milioni di semi che distribuiscono le mie due carte; Corro il mio RNG altre 2 milioni di volte per trovare il 2% di quei mazzi che producono il 7 di fiori come terza carta, e siamo scesi a soli 40 mila mazzi.

Vedi come va. Corro il mio RNG 40000 più volte per trovare tutti i semi che producono la mia quarta carta, e questo ci porta fino a 800 mazzi, e poi eseguo altre 800 volte per ottenere i ~ 20 semi che producono la mia quinta carta, e ora ho appena genera quei venti mazzi di carte e so che hai una delle venti mani possibili. Inoltre, ho un'ottima idea di ciò che disegnerò dopo.

Ora capisci perché la vera casualità è importante? Nel modo in cui lo descrivi, pensi che la distribuzione sia importante, ma la distribuzione non è ciò che rende casuale un processo. L'imprevedibilità è ciò che rende casuale un processo.

AGGIORNARE

Sulla base dei commenti (ora eliminati a causa della loro natura non costruttiva), almeno lo 0,3% delle persone che hanno letto questo è confuso riguardo al mio punto. Quando le persone sostengono contro i punti che non ho fatto, o peggio, sostengono per i punti che ho fatto fanno sul presupposto che io non li faccio, allora so che ho bisogno di spiegare in modo più chiaro e con attenzione.

Sembra esserci una particolare confusione nella distribuzione delle parole, quindi desidero richiamare con attenzione gli usi.

Le domande a portata di mano sono:

  • In cosa differiscono i numeri pseudocasuali e quelli veramente casuali?
  • Perché la differenza è importante?
  • Le differenze hanno qualcosa a che fare con la distribuzione dell'output del PRNG?

Cominciamo considerando il modo perfetto per generare un mazzo casuale di carte con cui giocare a poker. Quindi vedremo come le altre tecniche per la generazione dei deck sono diverse e se è possibile sfruttare questa differenza.

Partiamo dal presupposto che abbiamo una scatola magica etichettata TRNG. Come suo input gli diamo un numero intero n maggiore o uguale a uno e come output ci dà un numero veramente casuale compreso tra uno e n, incluso. L'output della casella è del tutto imprevedibile (quando viene dato un numero diverso da uno) e qualsiasi numero tra uno e n è probabile come un altro; vale a dire che la distribuzione è uniforme . (Esistono altri controlli statistici più avanzati di casualità che potremmo eseguire; sto ignorando questo punto in quanto non è pertinente al mio argomento. TRNG è perfettamente statisticamente casuale per ipotesi.)

Iniziamo con un mazzo di carte non mischiato. Chiediamo alla casella un numero compreso tra 1 e 52 - ovvero TRNG(52). Qualunque numero restituisca, contiamo quelle carte dal nostro mazzo ordinato e rimuoviamo quella carta. Diventa la prima carta nel mazzo mescolato. Quindi chiediamo TRNG(51)e facciamo lo stesso per selezionare la seconda carta e così via.

Un altro modo di vederlo è: ce ne sono 52! = 52 x 51 x 50 ... x 2 x 1 mazzi possibili, che è approssimativamente 2 226 . Ne abbiamo scelto uno a caso.

Ora distribuiamo le carte. Quando guardo le mie carte non ho idea di quali carte tu abbia. (A parte il fatto ovvio che non hai nessuna delle carte che ho.) Potrebbero essere qualsiasi carta, con uguale probabilità.

Quindi fammi assicurarmi di spiegarlo chiaramente. Abbiamo una distribuzione uniforme di ogni singola uscita di TRNG(n); ognuno prende un numero compreso tra 1 e n con probabilità 1 / n. Inoltre, il risultato di questo processo è che abbiamo scelto uno dei 52! possibili piattaforme con una probabilità di 1/52 !, quindi la distribuzione sopra l'insieme di possibili ponti è anche uniforme.

Tutto ok.

Supponiamo ora di avere una scatola meno magica, etichettata PRNG. Prima di poterlo utilizzare, è necessario eseguire il seeding con un numero senza segno a 32 bit.

A parte: perché 32 ? Non è possibile eseguire il seeding con un numero di 64 o 256 o 10000 bit? Sicuro. Ma (1) in pratica la maggior parte dei PRNG standardizzati sono seminati con un numero a 32 bit e (2) se hai 10000 bit di casualità per creare il seme, allora perché stai usando un PRNG? Hai già una fonte di 10000 bit di casualità!

Comunque, tornando a come funziona il PRNG: dopo che è stato seminato, puoi usarlo nello stesso modo in cui lo usi TRNG. Cioè, gli passi un numero, n, e ti restituisce un numero compreso tra 1 e n, incluso. Inoltre, la distribuzione di tale output è più o meno uniforme . Cioè, quando chiediamo PRNGun numero compreso tra 1 e 6, otteniamo 1, 2, 3, 4, 5 o 6 ciascuno circa un sesto del tempo, indipendentemente dal seme.

Voglio sottolineare questo punto più volte perché sembra essere quello che confonde alcuni commentatori. La distribuzione del PRNG è uniforme in almeno due modi. In primo luogo, supponiamo di scegliere un seme particolare. Ci aspetteremmo che la sequenza PRNG(6), PRNG(6), PRNG(6)...un milione di volte produrrebbe una distribuzione uniforme dei numeri tra 1 e 6. E in secondo luogo, se scegliamo un milione di semi diversi e chiamassimo PRNG(6) una volta per ogni seme, ci aspetteremmo di nuovo una distribuzione uniforme dei numeri da 1 a 6. L'uniformità del PRNG attraverso una di queste operazioni non è rilevante per l'attacco che sto descrivendo .

Si dice che questo processo sia pseudo-casuale perché il comportamento della scatola è in realtà completamente deterministico; sceglie da uno dei 2 32 possibili comportamenti basati sul seme. Cioè, una volta che viene seminato, PRNG(6), PRNG(6), PRNG(6), ... produce una sequenza di numeri con una distribuzione uniforme, ma quella sequenza è interamente determinata dal seme. Per una determinata sequenza di chiamate, ad esempio PRNG (52), PRNG (51) ... e così via, ci sono solo 2 32 sequenze possibili. Il seme essenzialmente sceglie quale otteniamo.

Per generare un mazzo il server ora genera un seme. (Come? Torneremo a quel punto.) Poi si chiamano PRNG(52), PRNG(51)e così via per generare il ponte, simile a prima.

Questo sistema è suscettibile all'attacco che ho descritto. Per attaccare il server, prima di tutto, seminiamo la nostra copia della scatola con 0 e chiediamo PRNG(52)e annotiamo. Quindi ri-seminiamo con 1, chiediamo PRNG(52)e scriviamo, fino a 2 32 -1.

Ora, il server di poker che utilizza PRNG per generare mazzi deve in qualche modo generare un seme. Non importa come lo fanno. Potrebbero chiamare TRNG(2^32)per ottenere un seme veramente casuale. Oppure potrebbero prendere il tempo corrente come seme, il che non è affatto casuale; So che ora è tanto quanto te. Il punto del mio attacco è che non importa, perché ho il mio database . Quando vedo la mia prima carta posso eliminare il 98% dei semi possibili. Quando vedo la mia seconda carta posso eliminare il 98% in più, e così via, fino a quando non riesco ad arrivare a una manciata di possibili semi e sapere con molta probabilità cosa c'è nella tua mano.

Ora, ancora una volta, voglio sottolineare che qui il presupposto è che se chiamassimo PRNG(6)un milione di volte otterremmo ogni numero circa un sesto delle volte . Quella distribuzione è (più o meno) uniforme e se l'uniformità di quella distribuzione è tutto ciò che ti interessa , va bene. Il punto della domanda era : ci sono altre cose PRNG(6)che ci interessano della distribuzione? e la risposta è . Ci preoccupiamo anche dell'imprevedibilità .

Un altro modo di esaminare il problema è che anche se la distribuzione di un milione di chiamate PRNG(6)potrebbe andare bene, poiché il PRNG sta scegliendo tra solo 2 32 possibili comportamenti, non può generare tutti i possibili deck. Può generare solo 2 32 dei 2 226 mazzi possibili; una piccola frazione. Quindi la distribuzione sul set di tutti i deck è pessima. Ma ancora una volta, l'attacco fondamentale qui si basa sulla nostra capacità di prevedere con successo il comportamento passato e futuro di PRNGun piccolo campione della sua produzione.

Consentitemi di dirlo una terza o quattro volte per assicurarmi che questo affondi. Ci sono tre distribuzioni qui. Innanzitutto, la distribuzione del processo che produce il seme casuale a 32 bit. Questo può essere perfettamente casuale, imprevedibile e uniforme e l'attacco continuerà a funzionare . In secondo luogo, la distribuzione di un milione di chiamate a PRNG(6). Questo può essere perfettamente uniforme e l'attacco continuerà a funzionare. Terzo, ho descritto la distribuzione dei mazzi scelti dal processo pseudo-casuale. Quella distribuzione è estremamente scarsa; solo una minima parte dei possibili mazzi IRL può essere scelta. L'attacco dipende dalla prevedibilità del comportamento del PRNG in base alla conoscenza parziale del suo output .

A parte: questo attacco richiede che l'attaccante sappia o sia in grado di indovinare quale sia l'algoritmo esatto utilizzato dal PRNG. Se questo è realistico o no è una domanda aperta. Tuttavia, quando si progetta un sistema di sicurezza, è necessario progettarlo per proteggerlo dagli attacchi anche se l'utente malintenzionato conosce tutti gli algoritmi nel programma . Detto in altro modo: la parte di un sistema di sicurezza che deve rimanere segreta affinché il sistema sia sicuro è chiamata "chiave". Se il tuo sistema dipende dalla sua sicurezza dagli algoritmi che usi come segreto, la tua chiave contiene quegli algoritmi . Questa è una posizione estremamente debole in cui trovarsi!

Andare avanti.

Supponiamo ora di avere una terza scatola magica etichettata CPRNG. È una versione crittografica di PRNG. Prende un seme a 256 bit anziché un seme a 32 bit. Condivide con PRNGla proprietà che il seme sceglie tra uno di 2 256 comportamenti possibili. E come le altre nostre macchine, ha la proprietà che un gran numero di chiamate CPRNG(n)produce una distribuzione uniforme dei risultati tra 1 e n: ognuno avviene 1 / n del tempo. Possiamo eseguire il nostro attacco contro di esso?

Il nostro attacco originale ci impone di memorizzare 2 32 mappature dai semi a PRNG(52). Ma 2 256 è un numero molto più grande; è del tutto impossibile eseguirlo CPRNG(52)più volte e archiviare i risultati.

Ma supponiamo che ci sia un altro modo per prendere il valore di CPRNG(52)e da ciò dedurre un fatto sul seme? Finora siamo stati piuttosto stupidi, costringendo solo brutalmente tutte le possibili combinazioni. Possiamo guardare dentro la scatola magica, capire come funziona e dedurre fatti sul seme in base all'output?

No. I dettagli sono troppo complicati da spiegare, ma i CPRNG sono progettati in modo intelligente in modo che sia impossibile dedurre qualsiasi fatto utile sul seme dal primo output di CPRNG(52)o da qualsiasi sottoinsieme dell'output, non importa quanto sia grande .

OK, quindi ora supponiamo che il server stia usando CPRNGper generare deck. Ha bisogno di un seme a 256 bit. Come sceglie quel seme? Se sceglie un valore che un attaccante può prevedere, improvvisamente l'attacco diventa di nuovo praticabile . Se riusciamo a determinare quello dei 2 256 possibili seed, è probabile che solo quattro miliardi di essi saranno scelti dal server, quindi saremo di nuovo in affari . Possiamo montare di nuovo questo attacco, prestando attenzione solo al piccolo numero di semi che possono essere generati.

Pertanto, il server dovrebbe lavorare per garantire che il numero di 256 bit sia distribuito uniformemente , ovvero ogni possibile seed viene scelto con probabilità di 1/2 256 . Fondamentalmente il server dovrebbe chiamare TRNG(2^256)-1per generare il seme per CPRNG.

E se potessi hackerare il server e scrutarlo per vedere quale seme è stato scelto? In tal caso, l'attaccante conosce l'intero passato e il futuro del CPRNG . L'autore del server deve proteggersi da questo attacco! (Certo, se riesco a montare con successo questo attacco, probabilmente posso anche trasferire semplicemente i soldi sul mio conto bancario direttamente, quindi forse non è poi così interessante. Il punto è: il seme deve essere un segreto difficile da indovinare, e un un numero a 256 bit veramente casuale è davvero difficile da indovinare.)

Tornando al mio precedente punto sulla difesa in profondità: il seme a 256 bit è la chiave di questo sistema di sicurezza. L'idea di un CPRNG è che il sistema è sicuro fintanto che la chiave è sicura ; anche se ogni altro fatto sull'algoritmo è noto, fintanto che puoi mantenere segreta la chiave, le carte dell'avversario sono imprevedibili.

OK, quindi il seme dovrebbe essere sia segreto che uniformemente distribuito perché se non lo è, possiamo montare un attacco. Partiamo dal presupposto che la distribuzione degli output di CPRNG(n)sia uniforme. Che dire della distribuzione sul set di tutti i mazzi possibili?

Potresti dire: ci sono 2 256 sequenze possibili emesse dal CPRNG, ma ci sono solo 2 226 mazzi possibili. Quindi ci sono più sequenze possibili rispetto ai deck, quindi stiamo bene; ogni possibile mazzo IRL è ora (con alta probabilità) possibile in questo sistema. E questo è un buon argomento tranne ...

2 226 è solo un'approssimazione di 52 !. Dividilo. 2 256/52 ! non può essere un numero intero perché, per prima cosa, 52! è divisibile per 3 ma nessuna potenza di due lo è! Dal momento che questo non è un numero intero ora abbiamo la situazione in cui tutti i mazzi sono possibili , ma alcuni mazzi sono più probabili di altri .

Se ciò non è chiaro, considera la situazione con numeri più piccoli. Supponiamo di avere tre carte, A, B e C. Supponiamo di usare un PRNG con un seme a 8 bit, quindi ci sono 256 possibili semi. Esistono 256 possibili output in PRNG(3)base al seme; non c'è modo di avere un terzo di essi come A, un terzo di essi B e un terzo di loro C perché 256 non è uniformemente divisibile per 3. Ci deve essere un piccolo orientamento verso uno di essi.

Allo stesso modo, 52 non si divide uniformemente in 2 256 , quindi ci deve essere una certa propensione verso alcune carte come la prima carta scelta e una distorsione da altre.

Nel nostro sistema originale con un seme a 32 bit c'era un grosso pregiudizio e la stragrande maggioranza dei mazzi possibili non fu mai prodotta. In questo sistema è possibile produrre tutti i deck, ma la distribuzione dei deck è ancora imperfetta . Alcuni mazzi sono leggermente più probabili di altri.

Ora la domanda è: abbiamo un attacco basato su questo difetto? e la risposta è in pratica, probabilmente no . CPRNGs sono progettati in modo che se il seme sia realmente casuale , allora è computazionalmente impossibile capire la differenza tra CPRNGe TRNG.

OK, quindi riassumiamo.

In cosa differiscono i numeri pseudocasuali e quelli veramente casuali?

Differiscono nel livello di prevedibilità che esibiscono.

  • I numeri veramente casuali non sono prevedibili.
  • Tutti i numeri pseudo-casuali sono prevedibili se il seme può essere determinato o indovinato.

Perché la differenza è importante?

Perché ci sono applicazioni in cui la sicurezza del sistema si basa sull'imprevedibilità .

  • Se si utilizza un TRNG per scegliere ciascuna scheda, il sistema non è disponibile.
  • Se si utilizza un CPRNG per scegliere ciascuna carta, il sistema è sicuro se il seme è sia imprevedibile che sconosciuto.
  • Se viene utilizzato un PRNG normale con un piccolo spazio seme, il sistema non è sicuro indipendentemente dal fatto che il seme sia imprevedibile o sconosciuto; uno spazio di semi abbastanza piccolo è suscettibile agli attacchi di forza bruta del tipo che ho descritto.

La differenza ha a che fare con la distribuzione dell'output del PRNG?

L'uniformità di distribuzione o la sua assenza per le singole chiamate a RNG(n)non è rilevante per gli attacchi che ho descritto.

Come abbiamo visto, sia a PRNGche CPRNGproducono scarse distribuzioni della probabilità di scegliere un singolo mazzo di tutti i mazzi possibili. Il PRNGè notevolmente peggio, ma entrambi hanno problemi.

Un'altra domanda:

Se TRNG è molto meglio di CPRNG, che a sua volta è molto meglio di PRNG, perché qualcuno usa CPRNG o PRNG?

Due ragioni.

Primo: spese. TRNG è costoso . Generare numeri veramente casuali è difficile. I CPRNG danno buoni risultati per molte chiamate arbitrariamente con una sola chiamata a TRNG per il seed. Il lato negativo è ovviamente che devi mantenere segreto quel seme .

Secondo: a volte vogliamo prevedibilità e tutto ciò che ci interessa è una buona distribuzione. Se stai generando dati "casuali" come input di programma per una suite di test, e mostra un bug, sarebbe bello che eseguire di nuovo la suite di test produca di nuovo il bug!

Spero che ora sia molto più chiaro.

Infine, se ti è piaciuto, allora potresti goderti qualche ulteriore lettura sul tema della casualità e delle permutazioni:


20
Ok, ragazzi e ragazze. Per ora basta commentare. Se vuoi discuterne ulteriormente, vai a prenderti una chatroom, kthnxbye!
Ivo Flipse,

1
@Eric Ma il seme non viene resettato prima di ogni nuovo mazzo pescato, vero? Quindi, mentre hai ragione sul fatto che ci sono solo relativamente poche traiettorie da cui stiamo campionando, non sai esattamente dove ti trovi nella traiettoria al momento e le traiettorie si intersecano.
AS


Un buon (ma denso) trattamento delle problematiche correlate è nella TAOCP vol 2 di Knuth, sezione 3.5 “What Is a Random Sequence?” (P. 149), che inizia con definizioni illuminanti di sequenze equidistribuite, k-distribuite e distributed distribuite. Le sequenze pseudocasuali sono discusse in 3.5.F (p. 170). Vedi anche i criteri di pseudo casualità dalla teoria della complessità e dalla BSI tedesca .
ShreevatsaR,

160

Come dice Eric Lippert, non si tratta solo di distribuzione. Esistono altri modi per misurare la casualità.

Uno dei primi generatori di numeri casuali ha una sequenza nel bit meno significativo: alterna 0 e 1. Pertanto, l'LSB era prevedibile al 100%. Ma devi preoccuparti di più. Ogni bit deve essere imprevedibile.

Ecco un buon modo di pensare al problema. Diciamo che stai generando 64 bit di casualità. Per ogni risultato, prendi i primi 32 bit (A) e gli ultimi 32 bit (B) e crea un indice in un array x [A, B]. Ora esegui il test un milione di volte e, per ogni risultato, incrementa l'array a quel numero, ovvero X [A, B] ++;

Ora disegna un diagramma 2D, dove maggiore è il numero, più luminoso è il pixel in quella posizione.

Se è veramente casuale, il colore dovrebbe essere un grigio uniforme. Ma potresti avere degli schemi. Prendiamo ad esempio questo diagramma della "casualità" nel numero di sequenza TCP del sistema Windows NT:

Windows NT

o anche questo da Windows 98:

Windows 98

Ed ecco la casualità dell'implementazione del router Cisco (IOS). Cisco ISO

Questi diagrammi sono per gentile concessione del documento di Michał Zalewski . In questo caso particolare, se si può prevedere quale sarà il numero di sequenza TCP di un sistema, si può impersonare quel sistema quando si effettua una connessione a un altro sistema, il che consentirebbe il dirottamento delle connessioni, l'intercettazione della comunicazione, ecc. E anche se noi non è possibile prevedere il numero successivo il 100% delle volte, se è possibile creare una nuova connessione sotto il nostro controllo , è possibile aumentare le probabilità di successo. E quando i computer possono generare 100.000 connessioni in pochi secondi, le probabilità di un attacco riuscito vanno da astronomico a possibile o addirittura probabile.


30
È così brillante che mi fa venire le lacrime agli occhi. Dovrebbe esserci un'app che li crei per ogni sistema operativo (mobile / desktop / server) e piattaforma (JVM / Javascript / ecc.).
HDave

5
La funzione Windows Rand () è abbastanza buona! Produce una nuvola che non ha alcun modello apparente. Guarda la mia implementazione per provarlo (e altri algoritmi): github.com/Zalastax/visualize_random
Zalastax

93

Mentre i numeri pseudocasuali generati dai computer sono accettabili per la maggior parte dei casi d'uso riscontrati dagli utenti di computer, ci sono scenari che richiedono numeri casuali completamente imprevedibili.

In applicazioni sensibili alla sicurezza come la crittografia, un generatore di numeri pseudocasuali (PRNG) può produrre valori che, sebbene apparentemente casuali, sono in realtà prevedibili da un utente malintenzionato. Qualcuno che tenta di decifrare un sistema di crittografia potrebbe essere in grado di indovinare le chiavi di crittografia se è stato utilizzato un PRNG e l'attaccante dispone di informazioni sullo stato del PRNG. Quindi, per tali applicazioni, è necessario un generatore di numeri casuali che produca valori che sono veramente indecifrabili. Si noti che alcuni PRNG sono progettati per essere crittograficamente sicuri e sono utilizzabili per tali applicazioni sensibili alla sicurezza.

Ulteriori informazioni sugli attacchi RNG sono disponibili in questo articolo di Wikipedia .


9
I PRNG crittografici esistono e sono ampiamente utilizzati. Possono da un seme di dimensioni modeste generare un flusso praticamente illimitato di numeri casuali. È computazionalmente impossibile distinguere un tale flusso da veri numeri casuali, quindi non è possibile ottenere ulteriori informazioni da qualsiasi porzione di tale flusso e per qualsiasi scopo pratico i numeri sono buoni quanto i veri numeri casuali.
aaaaaaaaaaaa,

Penso che il modo più semplice per spiegarlo sia la programmazione casuale di algoritmi di generazione di numeri. Ciò significa che è stata seguita una serie di istruzioni. Se esiste una serie di istruzioni, non può essere casuale.
Keltari,

6
@Keltari Ti manca l'elemento dell'entropia ... La maggior parte dei GNC (almeno quelli crittografici) raccolgono input da fonti esterne (ad esempio il movimento del mouse) e li usano come parte della condizione iniziale - quindi, la programmazione da Aa Bè programmata ma lo stato iniziale di A(dovrebbe) essere indelebile. Linux /dev/randommanterrà un'approssimazione di quanta entropia è disponibile e smetterà di dare numeri se scende troppo in basso.
Base

Per curiosità: perché le lampade laviche sono considerate "veramente casuali"? Capisco che mostra un comportamento piuttosto imprevedibile, ma qualcuno con una conoscenza abbastanza ferma della dinamica dei fluidi e di come questi fluidi interagiscono nell'ambiente gravitazionale terrestre può sicuramente produrre risultati "prevedibili", no? Certo, le lampade di lava sono imprevedibili, ma per me non sono affatto casuali, ma altamente prevedibili.
theGreenCabbage

1
@theGreenCabbage: sospetto che le lampade di lava siano caotiche. Dato un modello di computer abbastanza buono e cifre sufficientemente accurate, è possibile (in linea di principio) prevedere il comportamento per un po '. Ma poiché il sistema è caotico, due lampade di lava con il più piccolo cambiamento nelle condizioni iniziali divergeranno rapidamente nel comportamento. (E questo commento ignora gli attrattori caotici.)
dmm,

76

L'ho provato in Python: ecco il risultato di 60 milioni di rotoli. La variazione più alta è come 0,15. Non è così casuale come sta per arrivare?

In realtà, è così "buono", è cattivo ... Tutte le risposte esistenti si concentrano sulla prevedibilità data una piccola sequenza di valori iniziali. Voglio sollevare un altro problema:

    la tua distribuzione ha una deviazione standard molto più piccola di quanto dovrebbero fare i tiri casuali

La vera casualità solo non viene del tutto che vicino alla media "quasi esattamente 1 su come mai i numeri di molti può scegliere tra" che si sta utilizzando come indice di qualità.

Se guardi questa domanda di scambio di stack sulle distribuzioni di probabilità per più tiri di dado , vedrai una formula per la deviazione standard di N tiri di dado (presupponendo risultati realmente casuali):

 sqrt(N * 35.0 / 12.0).

Usando quella formula, la deviazione standard per:

  • 1 milione di rotoli è il 1708
  • 60 milioni di rotoli sono 13229

Se guardiamo i tuoi risultati:

  • 1 milione di rotoli: stddev (1000066, 999666, 1001523, 999452, 999294, 999999) è 804
  • 60 milioni di rotoli: stddev (9997653, 9997789, 9996853, 10006533, 10002774, 9998398) è 3827

Non puoi aspettarti che la deviazione standard di un campione finito corrisponda esattamente alla formula, ma dovrebbe avvicinarsi abbastanza. Eppure, con 1 milione di tiri hai meno della metà dello stddev corretto e per 60 milioni sei sotto un terzo - sta peggiorando e non è un caso ...

Gli pseudo-RNG tendono a muoversi attraverso una sequenza di numeri distinti, iniziando dal seme e non rivisitando il numero originale per un periodo specifico. Ad esempio, le implementazioni della vecchia rand()funzione della libreria C hanno normalmente un periodo di 2 ^ 32 e visiteranno ogni numero tra 0 e 2 ^ 32-1 esattamente una volta prima di ripetere il seme. Quindi, se hai simulato 2 ^ 32 dadi lancia il pre-modulo (%) i risultati includeranno ogni numero da 0 a 2 ^ 32, i conteggi per ogni risultato 1-6 sarebbero 715827883 o 715827882 (2 ^ 32 non è un multiplo di 6) e la deviazione standard quindi solo banalmente sopra 0. la formula sopra, la deviazione standard corretta per 2 ^ 32 tiri è 111924. Comunque, poiché il tuo numero di tiri pseudo casuali aumenta, converti verso 0 deviazione standard. Ci si può aspettare che il problema sia significativo quando il numero di rotoli è una frazione significativa del periodo, ma alcuni pseudo-RNG possono presentare problemi peggiori - o anche con un numero inferiore di campioni - rispetto ad altri.

Quindi, anche se non ti interessano le vulnerabilità crittografiche, in alcune applicazioni potresti avere a cuore distribuzioni che non hanno risultati eccessivamente, artificialmente uniformi. Alcuni tipi di simulazione stanno cercando in modo abbastanza specifico di elaborare le conseguenze dei risultati irregolari che si verificano naturalmente con grandi campioni di risultati casuali individuali, ma sono sottorappresentati nei risultati di alcuni pRNG. Se stai cercando di simulare il modo in cui un'enorme popolazione reagisce a qualche evento, questo problema potrebbe alterare radicalmente i tuoi risultati portando a conclusioni selvaggiamente inaccurate.


Per fare un esempio concreto: supponiamo che un matematico dica a un programmatore di macchine da poker che dopo 60 milioni di tiri simulati - usato per sfarfallare centinaia di piccole "luci" intorno allo schermo, se ci sono stati 10.013.229 o più sei, che il matematico prevede di essere 1 stddev lontano dalla media, dovrebbe esserci un piccolo pagamento. Secondo la regola 68–95–99.7 (Wikipedia) ciò dovrebbe avvenire circa il 16% delle volte (~ 68% rientra in una deviazione standard / solo la metà esterna è sopra). Con il tuo generatore di numeri casuali, questo deriva da circa 3,5 deviazioni standard sopra la media: meno dello 0,025% di probabilità - quasi nessun cliente ottiene questo vantaggio. Vedi la tabella delle deviazioni più alte nella pagina appena menzionata, in particolare:

| Range    | In range   | Outside range | Approx. freq. for daily event  |
| µ ± 1σ   | 0.68268... | 1 in 3        | Twice a week                   |
| µ ± 3.5σ | 0.99953... | 1 in 2149     | Every six years                |

Stai confrontando mele e arance qui. Le due deviazioni standard non hanno assolutamente nulla a che fare l'una con l'altra.
Jbeuh,

50

Ho appena scritto questo generatore di numeri casuali per generare tiri di dado

def get_generator():
  next = 1
  def generator():
    next += 1
    if next > 6:
      next = 1
    return next
  return generator

Lo usi così

>> generator = get_generator()
>> generator()
1
>> generator()
2
>> generator()
3
>> generator()
4
>> generator()
5
>> generator()
6
>> generator()
1

ecc. ecc. Saresti felice di usare questo generatore per un programma che ha lanciato una partita a dadi? Ricorda, la sua distribuzione è esattamente quello che ti aspetteresti da un generatore "veramente casuale"!

I generatori di numeri pseudo-casuali fanno essenzialmente la stessa cosa: generano numeri prevedibili con la distribuzione corretta. Sono cattivi per lo stesso motivo per cui il semplice generatore di numeri casuali sopra è cattivo - non sono adatti per situazioni in cui è necessaria un'imprevedibilità reale, non solo la corretta distribuzione.


2
"I generatori di numeri pseudo-casuali ... generano numeri prevedibili con la distribuzione corretta" - Solo perché è un PRNG non garantisce che abbia una distribuzione perfetta (in effetti, quelli commerciali in generale non lo fanno, esattamente per il motivi indicati in queste risposte). Sebbene possano essere prevedibili con informazioni sufficienti (l'algo usato, seme iniziale, valori di output, w / e), hanno ancora varianza.
Brian S,

3
Oltre il punto, lo so, ma get_generator = lambda: itertools.cycle(range(1,7)), generator = get_generator(), next(generator) # and so onè troppo elegante per non parlare :)
Janus Troelsen

2
@BrianS In realtà, un PRNG che non ha superato i test di distribuzione nel tempo sarebbe prevedibile per definizione. Quindi su qualche N grande, se ottieni anche un po 'di vantaggio da N / 2 teste in N lanci di monete, puoi iniziare a scommettere su teste e puoi vincere più di quanto perdi. Allo stesso modo, se hai una distribuzione perfetta di teste contro croce, ma le teste arrivano sempre in coppia, allora avresti di nuovo una ricetta per vincere. I test di distribuzione sono come sai che un PRNG va bene.
Jon Kiparsky,

1
Hai dimenticato nonlocal next:-).
Kos,

5
Un esempio ancora migliore: si ritiene che Pi sia normale , nel senso che qualsiasi sequenza di cifre di una determinata lunghezza in una base non appare più spesso di qualsiasi altra sequenza di quella lunghezza in quella base. Un algoritmo che, quando richiesto per n bit casuali, prende i successivi n bit di pi e li restituisce (il "seme" è il bit su cui si avvia), a lungo termine dovrebbe produrre una distribuzione perfettamente uniforme. Ma non lo vorresti ancora per il tuo generatore - qualcuno che conosce l'ultimo gruppo di bit che hai generato potrebbe trovare la prima volta che si verifica quella sequenza, supporre che il tuo seme sia lì e probabilmente sia corretto.
fino al

26

La generazione di numeri casuali che il tuo computer è in grado di eseguire è adatta alla maggior parte delle esigenze e difficilmente ti imbatterai in un momento in cui hai bisogno di un numero veramente casuale.

La vera generazione di numeri casuali ha i suoi scopi però. In sicurezza informatica, gioco d'azzardo, ampio campionamento statistico, ecc.

Se sei interessato alle applicazioni di numeri casuali, consulta l' articolo di Wikipedia .


12
Il grosso problema è quando hai bisogno di numeri casuali che un utente malintenzionato non può prevedere per motivi di sicurezza.
David Schwartz,

16
Sei sicuro che probabilmente ti imbatterai in un momento in cui hai bisogno di un numero davvero casuale. Basta aprire una pagina web che inizia con https://...
Jan Hudec,

3
@JanHudec: Bene, nell'uso quotidiano, avrai bisogno di numeri casuali sicuri nel momento in cui apri un programma, ben prima di digitare in una barra degli indirizzi: vedi randomizzazione del layout dello spazio degli indirizzi . Ecco perché succedono cose del genere .
Reid,

5
@JanHudec Stavo parlando in modo specifico nel senso che avresti bisogno di usare un generatore di numeri casuali online. I veri numeri casuali sono usati frequentemente, ma pochissime persone hanno effettivamente bisogno di generarli da soli.
Alex McKenzie,

2
Le slot machine usano anche un PRNG, non un TRNG. Il generatore funziona sempre e viene selezionato un numero nel momento esatto in cui viene premuto il pulsante di selezione. La somma del PRNG e il tempo di pressione del pulsante veramente casuale equivale a un TRNG.
Roger Dahl,

26

I numeri casuali generati dalle funzioni tipiche nella maggior parte dei linguaggi di programmazione non sono numeri puramente casuali. Sono numeri pseudo casuali. Dato che non sono numeri puramente casuali, possono essere indovinati con informazioni sufficienti sui numeri generati in precedenza. Quindi questo sarà un disastro per la sicurezza nella crittografia .

Ad esempio, la seguente funzione di generatore di numeri casuali utilizzata in glibcnon genera numeri puramente casuali. Il numero pseudo casuale generato da questo può essere indovinato. È un errore per problemi di sicurezza. C'è una storia che diventa disastrosa. Questo non dovrebbe essere usato in crittografia.

glibc random():
    r[i] ← ( r[i-3] + r[i-31] )  % (2^32)
    output  r[i] >> 1

Questo tipo di generatore di numeri pseudo casuali non dovrebbe mai essere usato in luoghi sensibili alla sicurezza, anche se statisticamente molto significativo.

Uno dei famosi attacchi alla chiave pseudo casuale è l'attacco al WEP 802.11b . WEP ha una chiave a lungo termine da 104 bit, concatenata con IV (contatore) a 24 bit per creare una chiave a 128 bit, che viene a sua volta applicata all'algoritmo RC4 per generare una chiave pseudo casuale.

( RC4( IV + Key ) ) XOR (message)

Le chiavi erano strettamente correlate tra loro. Qui, solo IV è aumentato di 1 in ogni passaggio e tutti gli altri sono rimasti uguali. Dal momento che questo non era puramente casuale, era disastroso e facilmente scomponibile. La chiave potrebbe essere recuperata analizzando circa 40000 frame, che è questione di minuti. Se il WEP utilizzava IV a 24 bit puramente casuale, potrebbe essere sicuro fino a circa 2 ^ 24 (quasi 16,8 milioni) di frame.

Quindi, quando possibile, si dovrebbe andare con un puro generatore di numeri casuali in questioni sensibili alla sicurezza.


3
Darei la colpa alle cose WEP su un protocollo mal progettato usando una cifra debole. Con i moderni stream cipher puoi usare un contatore come IV.
Codici InCos

2
Il problema principale con WEP era ripetere la chiave in 2 ^ 24 (quasi 16 milioni) di frame. È stato anche peggio con i relativi tasti che hanno permesso di decifrare il codice in circa 40000 frame. Il punto principale qui è che la chiave non è casuale. È strettamente correlato, quindi è così facile da decifrare.
Prabhu,

1
La pseudo-casualità è cattiva nella crittografia solo quando si generano chiavi crittografiche . Va benissimo oltre a ciò. In effetti, RC4 è poco più di un generatore di numeri pseudo-casuale seminato con l'espansione a 128 bit della chiave XORed sul testo in chiaro del messaggio.
Matt

12

La differenza è che i numeri generati pseudocasuali sono prevedibili (ripetendo) dopo qualche tempo in cui i numeri casuali reali non lo sono. La lunghezza necessaria per ripetere dipende dalla lunghezza del seme utilizzato per la sua generazione.

Ecco un bel video sull'argomento: http://www.youtube.com/watch?v=itaMNuWLzJo


Predictability! = Ripetizione. Mersenne Twister ne è un buon esempio. Sulla maggior parte dell'implementazione dopo 624 Int32 è possibile prevedere tutti i numeri successivi, ma la sequenza di Mersenne Twister è molto più lunga di quella (2 ^ 19937 - 1).
HoLyVieR

Non capisco perché questa risposta non sia stata messa in pila, poiché mi sembra che questa sia la risposta precisa e concisa alla domanda, almeno in parte. I numeri pseudo casuali possono essere facilmente previsti dopo alcune estrazioni, il numero di estrazioni varia con l'algoritmo pseudo casuale "qualità". La selezione di un algoritmo "buono" sta esaminando gli aspetti: 1. ogni valore è disegnato in eguale frequenza (distribuzione), 2. ci vuole un "lungo tempo" per riavviare la sequenza all'inizio e ricominciare a disegnare gli stessi numeri nel stesso ordine.
Min.

"i numeri casuali veri non sono [prevedibili]". Per oggi questo è vero. Ora, se crediamo nella teoria del Big Bang, e abbiamo un sacco di potere per calcolare lo stato dell'Universo in qualsiasi momento dopo il BB, basato sulla fisica, allora ... siamo in grado di prevedere il futuro, incluso il fatto che Sto scrivendo questo commento molto esatto. Giusto?
Min.

Ciò è ipoteticamente vero, tuttavia, considerando il vasto grado di entropia coinvolto nelle azioni effettive dei corpi reali, la potenza di calcolo richiesta sarebbe ridicolmente enorme. Pensa ai continenti coperti dai computer. Inoltre, a causa della dipendenza dallo stato precedente, lo stato di ogni corpo nell'universo in ogni momento dovrebbe essere memorizzato, il che per definizione richiederebbe più spazio di quello disponibile nell'universo, completamente riempito con apparati di memoria
TheEnvironmentalist

@TheEnvironmentalist - Ah! "Continenti coperti da computer" ... non è forse questa la "Guida alla galassia degli autostoppisti"? ;-)
ysap

10

Supponiamo che un numero pseudo casuale possa essere indovinato da chiunque prima che venga generato.

Per applicazioni banali va bene una pseudo casualità, come nel tuo esempio, otterrai approssimativamente la percentuale corretta (circa 1/6 del set di risultati totale) con alcune variazioni minori (che vedresti se avessi tirato un dado 600k volte);

Tuttavia, quando si tratta di cose come la sicurezza del computer; È richiesta la vera casualità.

Ad esempio, l'algoritmo RSA inizia con il computer che sceglie due numeri casuali (P e Q) e quindi esegue diversi passaggi verso quei numeri per generare i numeri speciali noti come chiavi pubbliche e private. (La parte importante di una chiave privata è che è privata e nessun altro lo sa!)

Se un utente malintenzionato può sapere quali sono i due numeri "casuali" che il tuo computer sceglierà, possono fare gli stessi passi per calcolare la tua chiave privata (quella che nessun altro dovrebbe sapere!)

Con la tua chiave privata, un utente malintenzionato può fare cose come a) Parla con la tua banca fingendo di essere te, b) Ascolta il tuo traffico Internet "sicuro" ed essere in grado di decodificarlo, c) Travestimento tra te e altre parti su Internet.

Ecco dove è richiesta la vera casualità (cioè non poter essere indovinati / calcolati).


10

Il primo numero casuale che io abbia mai usato aveva l'eccellente proprietà che di due numeri casuali consecutivi, il secondo era più grande con una probabilità di 0,6. Non 0,5. E il terzo era più grande del secondo con probabilità 0,6 e così via. Puoi immaginare come questo rovina una simulazione.

Alcune persone non mi crederebbero che ciò sia stato possibile anche con la distribuzione equa dei numeri casuali, ma è ovviamente possibile se si osserva la sequenza (1, 3, 5, 2, 4, 1, 3, 5, 2, 4, ...) dove il secondo di due numeri è più grande con probabilità 0,6.

D'altra parte, per le simulazioni può essere importante essere in grado di riprodurre numeri casuali. Supponiamo che tu esegua una simulazione del traffico e desideri scoprire come alcune azioni che potresti intraprendere potrebbero migliorare il traffico. In tal caso, si desidera essere in grado di ricreare esattamente gli stessi dati sul traffico (come le persone che cercano di entrare in una città) con diverse azioni che si è tentato di migliorare il traffico.


8

La risposta breve è che di solito le persone richiedono "vera casualità" per una cattiva ragione, vale a dire che non hanno alcuna comprensione della crittografia.

Le primitive crittografiche come stream cipher e CSPRNG vengono utilizzate per produrre enormi flussi di bit imprevedibili dopo che sono stati alimentati alcuni bit imprevedibili.

L'attento lettore ora avrà capito che c'è un problema di bootstrap qui: dobbiamo raccogliere alcuni frammenti di entropia per iniziare tutto. Quindi essere in grado di alimentarli a un CSPRNG che a sua volta fornirà felicemente tutti i bit imprevedibili di cui abbiamo bisogno. Pertanto è necessario un RNG hardware per eseguire il seeding di un CSPRNG . Questo è l'unico caso in cui l'entropia è richiesta nella verità.

(Penso che questo avrebbe dovuto essere pubblicato in Sicurezza o Crittografia.)

Modifica: Alla fine, si deve selezionare un generatore di numeri casuali che sia abbastanza buono per l'attività prevista e, per quanto riguarda la generazione di numeri casuali, l'hardware non equivale necessariamente al bene. Proprio come i cattivi PRNG, le fonti casuali hardware di solito hanno pregiudizi.

Modifica: alcune persone qui assumono un modello di minaccia in cui un utente malintenzionato potrebbe leggere lo stato interno di un CSPRNG e da lì giungere alla conclusione che i CSPRNG non sono una soluzione sicura. Questo è un esempio di modellazione di thread scadente. Se un attaccante possiede il tuo sistema, il gioco è finito, chiaro e semplice. Non fa alcuna differenza se si utilizza un TRNG o un CSPRNG a questo punto.

Modifica: Quindi, per riassumere tutto questo ... L'entropia è necessaria per seminare un CSPRNG. Una volta fatto ciò, un CSPRNG fornirà tutti i bit imprevedibili di cui abbiamo bisogno per le applicazioni di sicurezza molto più velocemente di quanto possiamo (normalmente) raccogliere entropia. Se non è necessaria l'imprevedibilità, ad esempio per la simulazione, un Mersenne Twister fornirà numeri con buone proprietà statistiche a un tasso molto più elevato.

Modifica: chiunque desideri comprendere il problema della generazione sicura di numeri casuali dovrebbe leggere questo: http://www.cigital.com/whitepapers/dl/The_Importance_of_Reliable_Randomness.pdf


2
Non è necessariamente una domanda di sicurezza. Penso che ci siano ragioni per usare numeri veramente casuali che non implicano sicurezza. Se stavo facendo delle ricerche scientifiche che dipendono da numeri casuali ed era per qualsiasi motivo fondamentale che i numeri fossero il più casuali possibile, approfitterei sicuramente di un RNG hardware in modo da poter essere certo che tutte le proprietà osservate non sono dovute a stranezze del RNG.
Kef Schecter,

3
@KefSchecter I loro PRNG hardware ascoltati generalmente hanno un output distorto e / o correlato. Hanno bisogno di una fase di post elaborazione per trasformarla in output indipendente uniforme. Non vi è motivo di credere che questa fase di post-elaborazione sia più affidabile di un moderno codice di flusso. Sicuramente mi fiderei di più del codice di flusso. Come bonus extra è riproducibile, il che è prezioso nella scienza.
CodesInChaos,

OK, abbastanza giusto. Ma lo stesso non si applicherebbe allo stesso modo alle applicazioni di crittografia? Anche la risposta fornita qui dice che è necessario un RNG hardware per seeding CSPRNG.
Kef Schecter,

2
@KefSchecter Sì, le applicazioni di crittografia richiedono numeri casuali reali per eseguire il seeding del CSPRNG. Ma per tutto il resto possiamo usare quel CSPRNG.
CodesInChaos,

@KefSchecter: le applicazioni crittografiche richiedono che il flusso non sia riproducibile dal mondo intero. Al contrario, nelle applicazioni scientifiche, essere in grado di dimostrare che i numeri "casuali" che si stanno utilizzando non sono stati semplicemente scelti per mostrare la propria analisi sotto una buona luce. Ad esempio, se uno annuncia dopo aver annunciato i propri metodi che genererà i dati in un certo modo utilizzando i numeri della lotteria di stato del giorno successivo, i lettori possono essere in qualche modo sicuri che non si siano confusi i risultati anche se il disegno del giorno della settimana ha solo una dozzina di dozzine pezzetti di entropia.
supercat,

7

Non tutti i PRNG sono adatti a tutti gli usi. Ad esempio, Java.util.SecureRandom utilizza l'hash SHA1, che ha una dimensione di output di 160 bit. Ciò significa che ci sono 2 160 possibili flussi di numeri casuali che possono provenire da esso. Semplice come quella. Non è possibile ottenere più di 2 160 valori dello stato interno. Quindi non puoi ottenere più di 2 160 flussi univoci di numeri casuali da un singolo seme, indipendentemente da dove provenga il tuo seme. Si crede che Windows CryptGenRandom utilizzi uno stato di 40 byte, ha 2 320 possibili flussi di numeri casuali.

Il numero di modi per mescolare un mazzo standard da 52 carte è 52 !, ovvero circa 2222 . Pertanto, indipendentemente dal seeding, non è possibile utilizzare Java.util.SecureRandom per mescolare un mazzo di carte. Ci sono circa 2 66 possibili mescolamenti che non può produrre. Certo, non sappiamo quali siano ...

Quindi, se avessi una fonte, per esempio, 256 bit di vera casualità (ad esempio, da una scheda Quantis RNG), potrei seminare un PRNG come CryptGenRandom () con quel seme e quindi usare il PRNG per mescolare un mazzo di carte. Se riesco a correggere con una vera casualità ogni shuffle, questo andrà bene: imprevedibile e statisticamente casuale. Se avessi fatto la stessa cosa con Java.util.SecureRandom, ci sarebbero shuffles che non potevano essere prodotti, perché non potevano essere seminati con 256 bit di entropia e il suo stato interno non poteva rappresentare tutti i shuffles possibili.

Si noti che i risultati java.util.SecureRandom sarebbero sia imprevedibili che statisticamente casuali. Nessun test statistico identificherà mai un problema! Ma l'output dell'RNG non è abbastanza grande da coprire l'intero dominio di tutti gli output possibili necessari per simulare un mazzo di carte.

E ricorda, se aggiungi i jolly, è 54! che devi coprire, il che richiede circa 2 238 possibilità.


2
Perché ti importa che non possano accadere alcuni shuffle? Tale restrizione non ha alcun effetto osservabile.
CodesInChaos,

2
Sono un po 'sbalordito dalla domanda. Per le società di gioco fortemente regolamentate, un simile pregiudizio proverebbe matematicamente che le tue possibilità di vincere il gioco di carte sono diverse con il computer che con un mazzo di carte di carta. Non importa se le possibilità sono migliori o peggiori. Sono DIVERSI. Il computer non è moralmente equivalente a un vero mazzo. Inoltre non possiamo caratterizzare la differenza. La società di gioco che deve affrontare rigide multe regolamentari si preoccuperà molto.
Paco Hope,

1
Ma è rilevabile. Lo rilevo usando un processo noto: revisione del codice sorgente e conoscenza del dominio problematico. Questo è straordinario. NON posso usare l'analisi statistica automatizzata. È rilevabile come qualcuno che usa java.util.Random o il Mersenne Twister. L'analisi statistica non è l'unico meccanismo di rilevamento valido per mancata corrispondenza del dominio RNG / problem. I fallimenti che superano quel rivelatore non sono, per definizione, successi.
Paco Hope,

1
Non sono mai stato in disaccordo con questa affermazione. Quello che ho detto è che l'analisi statistica non è una prova infallibile che l'RNG / PRNG sia corretto. Questo è un esempio di falso negativo. Dovrebbe essere errato, ma il test di output statistico lo supererà. Se uso SHA1 (1), SHA1 (2), SHA1 (3) ... SHA1 (n) come "RNG" che supererà anche i test statistici. È anche sbagliato. La definizione di corretto va oltre la definizione di "supera i test statistici". Il superamento di test statistici è necessario, ma non sufficiente.
Paco Hope,

4
@CodesInChaos: L'argomento "non conosciamo un attacco che può trarre vantaggio dal fatto che la stragrande maggioranza dei possibili shuffles-IRL non verrà mai prodotta" non implica che un tale attacco sia impossibile, solo che non Non so cosa sia o come difenderlo. L'atteggiamento giusto in quel caso è quello di eliminare la possibilità di attacco eliminando la condizione: creare un RNG di qualità sufficiente da poter effettivamente generare ogni possibile mazzo.
Eric Lippert,

6

I numeri pseudocasuali sono generati usando una funzione matematica e un valore iniziale (chiamato seme ), mentre i numeri casuali non lo sono. La loro prevedibilità li rende incredibilmente utili per i replay di gioco, poiché devi solo salvare il seed e l'input del giocatore: l'IA risponderà sempre nello stesso identico modo "casuale".


6

La differenza tra il numero casuale "vero" e il numero casuale "pseudo" è la prevedibilità. Questa risposta è già stata fornita.

Tuttavia, la prevedibilità non è necessariamente una cosa negativa, come mostra la maggior parte degli esempi. Ecco un esempio pratico di uno dei rari casi in cui la prevedibilità è buona: il sistema di posizionamento globale.

Ogni satellite utilizza un codice PRN distinto (i codici Gold ) adatto per la correlazione automatica o incrociata necessaria per la misurazione del tempo di propagazione del segnale. Per questi codici Gold la correlazione tra loro è particolarmente debole, rendendo possibile un'identificazione inequivocabile del satellite, ma consentendo il calcolo della distanza mediante la correlazione tra la sequenza emessa e il ricevitore.


2

Per un rapido controllo della casualità, prendi punti con coordinate casuali in [0; 1) e poi li metti nel cubo k-dimensionale. Quindi esegui la procedura per dividere questo cubo in sottocubi: ogni volume di sottocubo (o sottosfera) deve essere misurato correttamente con questa procedura con fluttuazioni secondo il teorema ben noto.

La qualità della casualità è importante quando incontri ...

  1. scopi di sicurezza. Quando generi un numero da utilizzare come parametro per la generazione della tua chiave, ed è ben prevedibile, il nemico lo scoprirà con una probabilità del 100% e renderà il campo di ricerca molto più piccolo.

  2. scopi scientifici. Nella scienza non si deve solo avere una media media in buone condizioni, ma anche le correlazioni tra vari numeri casuali devono essere eliminate. Quindi se prendi (a_i - a) (a_ {i + 1} -a) e trovi la sua distribuzione, deve corrispondere alle statistiche.

La correlazione di coppia è chiamata "casualità debole". Se vuoi una casualità reale, devi avere una correlazione di ordine elevato con più di 2 varianze.

Oggi solo i generatori di meccanica quantistica forniscono una vera casualità.


1

Perché la vera casualità è importante?

Ci sono fondamentalmente due ragioni principali per cui è necessaria la vera casualità:

  1. Se stai usando l'RNG per la crittografia (comprese cose come il gioco d'azzardo con soldi veri e la gestione di una lotteria), allora un PRNG ti renderà molto più debole di quanto l'analisi matematica (che presume che un TRNG) ti faccia credere. Il PRNG non sarà in realtà casuale, ma avrà uno schema: gli avversari possono sfruttare lo schema per decifrare un codice che avrebbe dovuto essere indistruttibile.
  2. Se si utilizza l'RNG per simulare input "casuali", ad esempio per la verifica di errori o la simulazione, un PRNG rende il vostro approccio debole. Quando non scopri alcun bug, ci sarà sempre quel fastidioso dubbio: c'è un bug che non si nota con il modello del mio PRNG, ma che si sarebbe presentato se avessi usato solo un TRNG? Le scoperte della mia simulazione descrivono accuratamente la realtà o il fenomeno che ho scoperto è semplicemente un artefatto del modello del PRNG?

Al di fuori di queste aree, non importa. Avvertenza: se il tuo PRNG è molto, molto cattivo, potrebbe non essere ancora adatto - non vuoi fare una partita a Craps in cui i dadi escono sempre anche, ai tuoi giocatori non piacerebbe.

In che modo il PRNG di Python non è abbastanza buono?

È molto improbabile che sarai in grado di rilevare le insidie ​​di un vero PRNG usando una metodologia così semplice. L'analisi statistica dei RNG è un campo scientifico a sé stante e sono disponibili alcuni test molto sofisticati per confrontare la "casualità" di un algoritmo. Questi sono molto più avanzati del tuo semplice tentativo.

Ogni sviluppatore di software che crea librerie del mondo reale, come gli sviluppatori Python, utilizza questi test statistici come parametro per vedere se la sua implementazione PRNG è abbastanza buona. Quindi, ad eccezione di casi di supervisione effettiva da parte degli sviluppatori, è molto improbabile che tu sia in grado di rilevare facilmente un modello in un PRNG del mondo reale. Ciò non significa che non vi sia alcun modello: un PRNG ha un modello per definizione.


0

Fondamentalmente, non è possibile dimostrare che una sorgente sia casuale dall'analisi matematica dell'output, ad esempio è necessario un modello fisico che dice che la sorgente è casuale (come nel decadimento radioattivo).

Puoi semplicemente eseguire test batch per trovare la correlazione statistica nei dati di output, in tal caso i dati si sono dimostrati non casuali (ma anche una fonte casuale può avere output non casuali o non sarà realmente casuale se non può fornire specifici produzione). Altrimenti se i test vengono superati, puoi dire che i dati sono pseudo casuali.

Superare alcuni test di casualità significa solo avere un buon PRNG (generatore di numeri pseudo casuali), che può essere utile per le applicazioni in cui la sicurezza non è coinvolta.

Se si tratta di sicurezza (ovvero crittografia, generazione di un tasto chiave, generazione di numeri casuali per il gioco d'azzardo ...) non è sufficiente avere un buon PRNG ma deve avere qualità aggiuntive, come se l'output della funzione non fosse facilmente intuibile dagli output precedenti, la funzione deve avere un costo computazionale desiderabile (abbastanza limitato per essere utilizzabile, ma abbastanza alto da sconfiggere i tentativi di forzatura bruta), l'hardware che esegue la funzione - o il dispositivo, nel caso dispari di oggi è un dispositivo analogico - non dovrebbe essere facilmente manomesso, ecc.

Avere un buon PRNG può essere utile nei giochi per creare schemi nuovi e imprevedibili, e nella crittografia - troppo ingombrante per spiegare in un singolo post, basti pensare come ruolo empirico quale uscita dalla procedura di crittografia dovrebbe essere pseudo-casuale, non mostrare schemi che potrebbe mettere in relazione i precedenti dati crittografati con i seguenti dati crittografati, oppure mettere in relazione dati di testo semplice con dati crittografati o mettere in relazione due diversi cifrati tra loro (quindi è possibile fare ipotesi sui testi semplici) ....


-5

Storia breve:

Genera un seme casuale utilizzando il microsecondo corrente del sistema.

Questo trucco è piuttosto vecchio ed è ancora funzionale.

Escludendo il fattore forza bruta, in cui posso determinare ogni combinazione "scommettendo" su tutti i numeri possibili e non è questo il punto di questa domanda, specialmente quando la maggior parte dei numeri casuali viene arrotondata prima del suo utilizzo.

Diciamo un esempio, posso determinare il seme usato usando solo 10 valori. Quindi, conoscendo il seme, posso indovinare il prossimo valore.

Se usassi il seed = 1, allora potrei ottenere la sequenza successiva:

1, 2, 3, 4, 5, 6, 7, 8, 9 ... (e deduco che il seme ha usato id 1 e il valore successivo 10)

Ma cosa succederà se cambiassi l'invio ogni "nth" valori ?. Cambiare il seme con i microsecondi attuali è un trucco economico (cioè, non richiede molti cicli della CPU).

Quindi la sequenza ora è: (seed = 1) 1, 2, 3, 4, 5, (seed = 2), 7, 9, 11, 13 ... (15?)

In questo caso:

a) Non posso dedurre quale seme è stato usato.

b) Ergo, non riesco a indovinare il prossimo valore.

c) L'unica ipotesi che posso fare è dedurre che il prossimo seme potrebbe essere un numero maggiore.

Ad ogni modo, la maggior parte dei moderni algoritmi di generatore casuale usa già questo trucco sotto il cofano.

Il fatto vero è che non abbiamo bisogno di un computer quantistico per creare un numero casuale "vero", l'imprecisione del nostro cristallo di quarzo del nostro computer funge da generatore casuale, anche l'efficienza casuale della nostra CPU è variabile senza considerare che la CPU di solito svolge più attività contemporaneamente.


2
Questa è un'idea piuttosto negativa ed è una fonte di vulnerabilità per cose che richiedono una sequenza veramente imprevedibile. Se prendi microsecondi, hai solo 10 ^ 6 possibilità di seme che è piuttosto basso.
HoLyVieR

@HoLyVieR: è sicuramente una cattiva idea se ti preoccupi della sicurezza, ma non è così male come te lo fai notare: normalmente useresti microsecondi dall'inizio del sistema (o unix epoca ...) che aumenta significativamente l'intervallo di valori possibili.
Mikera,

1
@mikera Non è meglio, il momento in cui la richiesta è stata elaborata è prevedibile. È un vettore di vulnerabilità per un buon numero di funzionalità di reimpostazione della password. Quegli script hanno generato token "casuali" con la tua tecnica e l'attaccante potrebbe trovare il token generato dal momento che trovare il momento in cui è stato eseguito è piuttosto banale ... è lo stesso tempo in cui è stata inviata la richiesta di reimpostazione della password + - 150ms.
HoLyVieR,

Certo, quella situazione è molto brutta. Ma la situazione in cui lo stato è stato seminato all'avvio del sistema e l'attaccante non ha un buon modo per indovinare il tempo di avvio non è poi così male. Potresti facilmente avere 10 ^ 12 possibili microsocondi tra cui scegliere, il che può rendere impossibile alcuni tipi di attacco. Per essere chiari: tutte queste soluzioni sono piuttosto cattive dal punto di vista crittografico, ma le costanti contano .
Mikera,

Per i server online, le informazioni sul tempo di attività del sistema vengono talvolta offerte pubblicamente. Oppure puoi ottenerlo da una pagina di stato "Incidenti. Server di nuovo attivo". Oppure puoi eseguire il ping, attendere un grande downtime e notare che potrebbe essere un riavvio della macchina (che richiederebbe alcune centinaia di milioni di tempo per il controllo, che è piuttosto basso).
Dereckson,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.