Ce este un generator de numere aleatorii?

Un generator de numere aleatorii (RNG) este un sistem care produce numere aleatorii sau pseudoaleatorii. Posibilitatea de a prezice cu adevărat următorul număr depinde de tipul generatorului. Unele generatoare se bazează pe un proces fizic, altele își calculează numerele cu un algoritm, iar unii algoritmi sunt construiți astfel încât nici cineva care le-a văzut rezultatele să nu poată prezice ce urmează. A părea aleatoriu și a fi imprevizibil sunt proprietăți diferite, iar cea mai mare parte a acestui articol este despre această diferență.

Generatoare de numere aleatorii hardware

Un generator de numere aleatorii hardware (HRNG), numit și generator de numere cu adevărat aleatorii (TRNG), își obține numerele dintr-un proces fizic. Cele mai vechi funcționează sub ochii noștri: o monedă aruncată în aer, un zar rostogolit, o ruletă. Mecanica descrie complet fiecare dintre ele, și totuși o ruletă bine construită rămâne imprevizibilă în practică, deoarece diferențe infime în felul în care începe fiecare rotire duc la rezultate cu totul diferite.

Generatoarele hardware moderne măsoară în schimb fenomene microscopice: zgomotul de alice (shot noise) și zgomotul termic din circuitele electronice, zgomotul atmosferic, efectele cuantice. Acestea sunt surse bune de entropie — imprevizibilitate care poate fi măsurată —, dar o sursă fizică nu este perfectă prin natura ei: poate avea abateri, poate deriva în timp și se poate defecta, așa că trebuie să i se evalueze și să i se monitorizeze calitatea, iar rezultatele trebuie prelucrate suplimentar acolo unde e nevoie, lucru descris de standarde precum NIST SP 800-90B. Sursele hardware sunt folosite acolo unde garanția contează cel mai mult — mai ales în criptografie, unde furnizează materialul de pornire imprevizibil pentru cheile din spatele unor protocoale precum Transport Layer Security (TLS).

Generatoare de numere pseudoaleatorii

Alternativa la un dispozitiv fizic este un algoritm. Un generator de numere pseudoaleatorii (PRNG) produce o secvență care pare aleatorie, dar este complet determinată de o valoare inițială numită sămânță (seed). Dacă dai aceeași sămânță aceluiași algoritm, obții de fiecare dată aceeași secvență. Acesta este un punct slab oriunde un rezultat trebuie să fie imprevizibil, iar sămânța sau starea internă pot fi ghicite ori reconstruite, și un avantaj oriunde un rezultat trebuie să fie reproductibil — o simulare sau un test poate fi rulat din nou exact la fel. PRNG-urile sunt, de asemenea, rapide, ieftine și ușor de implementat, motiv pentru care majoritatea programelor se bazează pe ele. Printre familiile cunoscute se numără generatorul congruențial liniar (LCG), generatoarele xorshift și Mersenne Twister.

Mersenne Twister

Algoritmul Mersenne Twister, publicat în 1997 de Makoto Matsumoto și Takuji Nishimura, este unul dintre cele mai folosite generatoare de numere pseudoaleatorii și generatorul implicit în multe limbaje de programare. Numele îi vine de la perioada sa — lungimea secvenței înainte ca aceasta să se repete —, care în varianta standard, MT19937, este numărul prim Mersenne 219937 − 1. Trece majoritatea testelor statistice de aleatorietate și se potrivește bine pentru simulări. Totuși, nu a fost conceput să păstreze secrete: din 624 de valori consecutive pe 32 de biți, oricine îi poate reconstrui starea internă și poate prezice fiecare valoare care urmează, așa că nu trebuie folosit pentru chei, parole sau orice altceva ce trebuie să rămână imprevizibil.

Generatoare criptografic sigure și entropie

Multe aplicații au nevoie de ambele lucruri deodată: viteza unui algoritm și imprevizibilitatea unei surse fizice. Răspunsul este un generator de numere pseudoaleatorii criptografic sigur (CSPRNG). Este tot un PRNG, dar construit astfel încât cine vede o parte din rezultatele lui să nu aibă nicio cale practică de a prezice restul, iar sămânța îi vine, și este reînnoită regulat, dintr-o sursă de entropie reală. O sămânță dintr-o sursă fizică nu face sigur un PRNG obișnuit; algoritmul trebuie să fie conceput pentru asta. O sursă fizică, precum zgomotul termic sau momentele în care au loc evenimentele hardware, furnizează o cantitate mică de aleatorietate reală, iar CSPRNG-ul obține din ea, mult mai rapid, o secvență lungă de valori. Această combinație este ceea ce un sistem de operare oferă programelor care rulează pe el și ceea ce se înțelege de obicei astăzi, în practică, prin „generator de numere aleatorii”. El produce chei de criptare, tokenuri de sesiune și parole.

Numere aleatorii în browser

JavaScript oferă unei pagini web două modalități integrate de a obține valori aleatorii, iar ele aparțin unor clase diferite. Math.random() este un PRNG obișnuit: standardul limbajului lasă alegerea algoritmului în seama fiecărui browser și nu promite nimic în privința securității — potrivit pentru o animație, nepotrivit pentru o extragere pe care cineva ar putea-o contesta. Cealaltă este Web Crypto API. Metoda sa crypto.getRandomValues() returnează valori aleatorii criptografic puternice, produse de un CSPRNG care primește sămânța din entropia sistemului de operare.

Generatorul nostru de numere aleatorii online folosește Web Crypto API pentru fiecare extragere, iar numerele sunt produse în browserul tău, nu pe un server. Aceeași sursă stă la baza celorlalte generatoare de pe acest site, fie că vrei să dai cu zarul, să arunci o monedă sau să generezi o parolă.

De la biți aleatorii la un număr din intervalul tău

Un generator criptografic sigur este doar jumătate dintr-o extragere corectă. El livrează biți bruți, iar programul trebuie să-i transforme într-un număr din intervalul tău — și aici se poate strecura o abatere. Să presupunem că sursa dă valorile de la 0 la 9 cu șanse egale și ai nevoie de un număr de la 0 la 5. Restul împărțirii la 6 pare soluția firească, dar atunci 0, 1, 2 și 3 pot ieși fiecare în două moduri, iar 4 și 5 într-unul singur, așa că fiecare dintre numerele de la 0 la 3 are o șansă de 20%, iar 4 și 5 doar câte 10%. O modalitate de a elimina abaterea este să renunți la valorile care nu se potrivesc și să extragi din nou; materialele despre numere aleatorii tratează subiectul în detaliu.

Încă două lucruri îi surprind pe oameni. Repetițiile sunt normale: când un număr întreg de la 1 la 10 este extras independent și toate numerele sunt la fel de probabile, numărul tocmai extras are aceeași șansă de 1 din 10 să iasă din nou ca oricare altul. O extragere fără repetiții este un alt tip de extragere, nu una mai aleatorie. Iar un generator corect nu face singur corectă întreaga procedură: lista participanților și numărul de încercări contează la fel de mult, așa cum explică articolul nostru despre cum să alegi câștigătorul unui concurs.