Liczby losowe to sekwencje wartości, których nie można przewidzieć, a każda z nich jest generowana niezależnie od poprzednich. Dawniej losowość uzyskiwano za pomocą metod fizycznych – rzutu monetą, kostką czy wyciągania numerów z urny. Pierwszą tablicę liczb losowych opublikował L. H. Tippett w 1927 roku pod tytułem Random Sampling Numbers.

Współczesna technologia wymaga miliardów liczb losowych generowanych w ułamkach sekund. Znajdują one zastosowanie w kryptografii, symulacjach naukowych, grach komputerowych, analizie danych i wielu innych dziedzinach. Problem polega na tym, że komputery są z natury deterministyczne – wykonują dokładnie te operacje, które im zaprogramowano. Dlatego powstały różne typy generatorów liczb losowych, z których każdy rozwiązuje ten problem w inny sposób.

W tym artykule przybliżamy trzy główne kategorie generatorów: pseudolosowe (PRNG), prawdziwie losowe (TRNG) i kryptograficznie bezpieczne (CSPRNG). Dowiesz się, jak działają, czym się różnią i kiedy sięgnąć po każdy z nich. Jeśli chcesz samodzielnie przetestować losowość, skorzystaj z naszego generatora liczb losowych.

Trzy typy generatorów liczb losowych

Generatory liczb losowych dzielą się na trzy główne kategorie, które różnią się zasadą działania, szybkością, poziomem bezpieczeństwa i zastosowaniami.

PRNG

Generatory pseudolosowe – algorytmy matematyczne tworzące sekwencje, które wyglądają na losowe, ale są w pełni deterministyczne.

TRNG

Generatory prawdziwie losowe – oparte na fizycznych zjawiskach losowych, takich jak szum elektroniczny czy zjawiska kwantowe.

CSPRNG

Kryptograficznie bezpieczne PRNG – wyspecjalizowane algorytmy pseudolosowe zaprojektowane z myślą o bezpieczeństwie.

Każdy z tych typów ma unikalne cechy, zalety i ograniczenia. W kolejnych sekcjach przyjrzymy się każdemu z nich szczegółowo, porównamy je ze sobą i pokażemy konkretne implementacje w popularnych językach programowania.

Generatory pseudolosowe (PRNG)

Generatory pseudolosowe (PRNG) to algorytmy komputerowe produkujące sekwencje liczb, które statystycznie przypominają losowe. Są w pełni deterministyczne – podając to samo ziarno początkowe (seed), zawsze otrzymamy identyczną sekwencję. To zarówno ich największa zaleta (powtarzalność w testach), jak i wada (przewidywalność).

Większość PRNG działa według prostego schematu: przyjmują wartość początkową, stosują wzór matematyczny do jej przekształcenia, produkują liczbę pseudolosową, a nowy stan wewnętrzny staje się punktem wyjścia dla następnej liczby. Popularne algorytmy to Linear Congruential Generator (LCG), Mersenne Twister i Xorshift.

Zalety PRNG

  • Bardzo szybkie działanie
  • Powtarzalność (przydatna w testach)
  • Niewielkie zapotrzebowanie na zasoby
  • Dostępność w każdym języku programowania

Ograniczenia PRNG

  • Nie generują prawdziwej losowości
  • Przewidywalne po odkryciu ziarna
  • Sekwencje powtarzają się po pewnym okresie
  • Nieodpowiednie do zastosowań kryptograficznych

Zastosowania PRNG

Generatory pseudolosowe świetnie sprawdzają się w zastosowaniach, gdzie szybkość jest ważniejsza niż nieprzewidywalność: generowanie losowych poziomów w grach, symulacje Monte Carlo, modelowanie statystyczne, walidacja krzyżowa w uczeniu maszynowym, testy oprogramowania (fuzzing) czy generowanie danych testowych. Jeśli chcesz szybko wylosować liczby do eksperymentu lub zabawy, nasz generator liczb wykorzystuje właśnie szybki algorytm pseudolosowy.

Przykład implementacji LCG

Poniżej prosty przykład Linear Congruential Generator – jednego z najstarszych algorytmów PRNG:

PHP:

function simpleLCG($seed = null) {
    static $state;
    if ($seed !== null) $state = $seed;
    if ($state === null) $state = time();

    $a = 1103515245;  // mnożnik (wartości z ANSI C)
    $c = 12345;        // przyrost
    $m = 2147483648;   // moduł (2^31)

    $state = ($a * $state + $c) % $m;
    return $state / $m; // wynik z zakresu 0-1
}

simpleLCG(42);                    // inicjalizacja z ziarnem
$random = simpleLCG() * 100;     // losowa liczba 0-100

Powyższy przykład służy celom edukacyjnym. W praktyce należy korzystać z wbudowanych funkcji generowania liczb, takich jak mt_rand() w PHP czy Math.random() w JavaScript.

Generatory prawdziwie losowe (TRNG)

Generatory prawdziwie losowe (TRNG) to urządzenia lub systemy generujące liczby na podstawie fizycznych zjawisk losowych – nieprzewidywalnych i niemożliwych do kontrolowania. W przeciwieństwie do PRNG, produkowane liczby są naprawdę losowe i nie da się ich odtworzyć.

TRNG czerpią losowość (entropię) z różnych fizycznych źródeł. Typowy system składa się z czujnika mierzącego zjawisko fizyczne, konwertera analogowo-cyfrowego oraz układu przetwarzającego surowe dane na użyteczne liczby losowe.

Źródła entropii w TRNG

  • Szum termiczny – losowe poruszanie się elektronów w przewodnikach
  • Zjawiska kwantowe – rozpad promieniotwórczy, splątanie kwantowe
  • Atmosferyczne szumy radiowe – naturalne zakłócenia elektromagnetyczne
  • Chaos laserowy – fluktuacje w emisji światła laserowego

Zalety TRNG

  • Prawdziwa, fizyczna losowość
  • Pełna nieprzewidywalność
  • Brak powtarzalności sekwencji
  • Odporność na ataki kryptograficzne

Ograniczenia TRNG

  • Wolniejsze od PRNG
  • Wymagają specjalistycznego sprzętu
  • Wyższy koszt implementacji
  • Wrażliwość na warunki środowiskowe

Przykłady rzeczywistych TRNG

Random.org to popularny serwis wykorzystujący atmosferyczne szumy radiowe do generowania prawdziwie losowych liczb, dostępnych przez API. Intel RDRAND to generator sprzętowy wbudowany w nowsze procesory Intel, czerpiący entropię z szumu elektronicznego. Quantis firmy ID Quantique to komercyjny generator kwantowy wykorzystujący zjawiska fizyki kwantowej. TRNG stosuje się głównie w krytycznych zastosowaniach kryptograficznych, legalnych loteriach państwowych, certyfikowanych kasynach i randomizowanych badaniach klinicznych.

Generatory kryptograficznie bezpieczne (CSPRNG)

Generatory kryptograficznie bezpieczne (CSPRNG) to specjalna kategoria generatorów pseudolosowych, łącząca szybkość PRNG z bezpieczeństwem zbliżonym do TRNG. Aby generator mógł być uznany za kryptograficznie bezpieczny, musi spełniać kilka warunków.

Wymagania dla CSPRNG

  • Odporność na przewidywanie – nawet znając dużą część sekwencji, nie można przewidzieć kolejnych liczb
  • Odporność na analizę wsteczną – nie można odtworzyć wcześniejszych wartości z aktualnego stanu
  • Wysoka entropia – brak statystycznych anomalii w generowanych sekwencjach
  • Bezpieczne zarządzanie stanem – stan wewnętrzny chroniony przed podejrzeniem

CSPRNG często łączą algorytmiczne generowanie z okresowym „dostrzykiwaniem" prawdziwej entropii ze źródeł sprzętowych, tworząc systemy hybrydowe. Stosuje się je w protokołach TLS/SSL, generowaniu tokenów sesji, uwierzytelnianiu dwuskładnikowym (2FA), systemach płatności elektronicznych, kryptowalutach i bankowości internetowej.

W systemach operacyjnych CSPRNG jest dostępny jako /dev/urandom w Linuxie, CryptGenRandom w Windows oraz jako randomizacja przestrzeni adresowej (ASLR) chroniąca przed atakami na pamięć. Jeśli interesuje Cię bezpieczeństwo haseł, sprawdź nasz generator haseł, który korzysta z kryptograficznie bezpiecznego źródła losowości.

Porównanie generatorów liczb losowych

Poniższa tabela zestawia kluczowe cechy trzech typów generatorów, co ułatwia wybór odpowiedniego rozwiązania.

Cecha PRNG TRNG CSPRNG
Źródło losowości Formuły matematyczne Zjawiska fizyczne Algorytmy + entropia
Prawdziwa losowość Nie Tak Częściowo
Szybkość Bardzo wysoka Niska Wysoka
Bezpieczeństwo Niskie Bardzo wysokie Wysokie
Powtarzalność Tak (deterministyczny) Nie Częściowo
Wymagania sprzętowe Minimalne Specjalistyczne Standardowe
Koszt Niski Wysoki Średni
Typowe zastosowania Gry, symulacje, testy Kryptografia, loterie Sieci, aplikacje, bankowość

Który generator wybrać?

PRNG – wybierz do gier, prostych aplikacji, symulacji naukowych i generowania danych testowych, gdzie szybkość jest ważniejsza niż nieprzewidywalność. TRNG – wybierz dla krytycznych zastosowań kryptograficznych, loterii z dużymi nagrodami i systemów wymagających najwyższego poziomu bezpieczeństwa. CSPRNG – wybierz do tokenów sesji, kluczy tymczasowych, haseł jednorazowych i większości zastosowań związanych z bezpieczeństwem – oferuje dobry kompromis między wydajnością a ochroną.

Zastosowania generatorów w praktyce

Generatory liczb losowych są wszechobecne we współczesnej technologii. Poniżej najważniejsze obszary, w których odgrywają kluczową rolę.

Cyberbezpieczeństwo

Generowanie kluczy szyfrujących (AES, RSA), podpisy cyfrowe, protokoły TLS/SSL, tworzenie silnych haseł i tokenów. Wymaga CSPRNG lub TRNG.

Gry i rozrywka

Proceduralne generowanie poziomów i map, systemy lootowe, zachowanie NPC, symulacja rzutów kostką, tasowanie kart. Zazwyczaj wystarcza PRNG.

Nauka i badania

Symulacje Monte Carlo, modelowanie stochastyczne, inicjalizacja wag sieci neuronowych, walidacja krzyżowa w uczeniu maszynowym, randomizowane badania kliniczne.

Finanse i ekonomia

Modelowanie ryzyka, symulacje rynków finansowych, wycena instrumentów pochodnych, transakcje blockchain i kryptowaluty, bezpieczna bankowość elektroniczna.

Więcej o roli losowości we współczesnych technologiach przeczytasz w artykule o liczbach losowych w uczeniu maszynowym i sztucznej inteligencji. Historię rozwoju generatorów losowych opisaliśmy w osobnym artykule o historii generatorów liczb losowych.

Implementacje w popularnych językach programowania

Każdy język programowania oferuje zarówno zwykłe generatory pseudolosowe, jak i funkcje kryptograficznie bezpieczne. Poniżej przegląd najważniejszych.

PHP

PHP – PRNG vs CSPRNG:

// PRNG – szybkie, ale nie kryptograficzne
$random = rand(1, 100);
$betterRandom = mt_rand(1, 100);        // Mersenne Twister

// CSPRNG – kryptograficznie bezpieczne (od PHP 7.0)
$secureInt = random_int(1, 100);
$secureBytes = random_bytes(16);
$token = bin2hex(random_bytes(32));      // bezpieczny token

JavaScript

JavaScript – przeglądarka i Node.js:

// PRNG – Math.random() (NIE do celów bezpieczeństwa)
const random = Math.random();
const randomInt = Math.floor(Math.random() * 100) + 1;

// CSPRNG – przeglądarka
const array = new Uint32Array(1);
window.crypto.getRandomValues(array);

// CSPRNG – Node.js
const crypto = require('crypto');
const secureBuffer = crypto.randomBytes(16);

Python

Python – moduły random vs secrets:

import random
import secrets

# PRNG – moduł random
random_num = random.randint(1, 100)
random_float = random.random()
random_element = random.choice(['a', 'b', 'c'])

# CSPRNG – moduł secrets (od Python 3.6)
secure_num = secrets.randbelow(100) + 1
secure_token = secrets.token_hex(16)
secure_choice = secrets.choice(['a', 'b', 'c'])

Java

Java – Random vs SecureRandom:

import java.util.Random;
import java.security.SecureRandom;

// PRNG
Random rand = new Random();
int randomNum = rand.nextInt(100) + 1;

// CSPRNG
SecureRandom secureRand = new SecureRandom();
int secureNum = secureRand.nextInt(100) + 1;
byte[] randomBytes = new byte[16];
secureRand.nextBytes(randomBytes);

Niezależnie od języka, zasada jest zawsze ta sama: do celów bezpieczeństwa (tokeny, klucze, hasła, sól) używaj wyłącznie funkcji kryptograficznie bezpiecznych, nigdy zwykłych generatorów pseudolosowych.

Często zadawane pytania

Czym różni się PRNG od TRNG?

PRNG (generator pseudolosowy) wykorzystuje algorytmy matematyczne i jest deterministyczny – to samo ziarno daje tę samą sekwencję. TRNG (generator prawdziwie losowy) opiera się na fizycznych zjawiskach losowych, takich jak szum termiczny czy zjawiska kwantowe, i generuje liczby naprawdę nieprzewidywalne.

PRNG jest szybszy i tańszy w implementacji, ale TRNG oferuje prawdziwą losowość wymaganą w krytycznych zastosowaniach kryptograficznych.

Kiedy używać CSPRNG zamiast zwykłego PRNG?

CSPRNG należy używać zawsze, gdy generowane liczby mają wpływ na bezpieczeństwo: tokeny sesji, klucze szyfrujące, hasła jednorazowe, sól do haszowania haseł, identyfikatory resetowania hasła. Sprawdź nasz generator haseł, który korzysta właśnie z CSPRNG.

Zwykły PRNG wystarczy do gier, symulacji naukowych, testów oprogramowania i wizualizacji danych, gdzie szybkość jest ważniejsza niż kryptograficzna nieprzewidywalność.

Czy Math.random() w JavaScript jest bezpieczny?

Nie. Math.random() jest generatorem pseudolosowym (PRNG) i nie powinien być używany w kontekstach wymagających bezpieczeństwa. Jego wyniki są potencjalnie przewidywalne.

Do celów kryptograficznych w przeglądarce należy używać window.crypto.getRandomValues(), a w Node.js modułu crypto. Te funkcje korzystają z kryptograficznie bezpiecznych źródeł losowości systemu operacyjnego.

Co to jest ziarno (seed) w generatorze pseudolosowym?

Ziarno (seed) to wartość początkowa, od której generator pseudolosowy rozpoczyna generowanie sekwencji. To samo ziarno zawsze daje identyczną sekwencję liczb – to przydatna cecha przy testowaniu i debugowaniu, ale wada z perspektywy bezpieczeństwa.

Dlatego w praktyce ziarno inicjalizuje się z możliwie nieprzewidywalnego źródła, np. aktualnego czasu systemowego, danych z urządzeń wejściowych lub entropii zebranej przez system operacyjny.

Jakie funkcje PHP służą do generowania bezpiecznych liczb losowych?

W PHP do generowania kryptograficznie bezpiecznych liczb służą random_int() (bezpieczna liczba całkowita z zakresu) i random_bytes() (bezpieczny ciąg losowych bajtów). Obie są dostępne od PHP 7.0.

Starsze funkcje rand() i mt_rand() nie są kryptograficznie bezpieczne i nie powinny być używane tam, gdzie bezpieczeństwo ma znaczenie.

Jak działają generatory losowe w komputerach?

Komputery wykorzystują dwa podejścia. Generatory pseudolosowe (PRNG) stosują wzory matematyczne do tworzenia sekwencji, które wyglądają na losowe, ale są w pełni deterministyczne. Generatory sprzętowe (TRNG) mierzą fizyczne zjawiska losowe, np. szum elektroniczny w procesorze.

Współczesne systemy operacyjne łączą oba podejścia – zbierają entropię ze sprzętu (ruchy myszy, dysk, sieć) i używają jej do zasilania algorytmów kryptograficznych. Więcej o algorytmach losowania przeczytasz w artykule o algorytmach losowania w komputerach.