Como funciona o gerador de números aleatórios e pseudoaleatórios
Um computador é uma máquina que segue instruções à risca. Então, como ele consegue jogar uma moeda, rolar um dado ou sortear um nome? A resposta curta: na maioria das vezes, ele nem gera números realmente aleatórios. Ele gera números que só parecem aleatórios, e para a maioria dos usos isso basta. Veja como funciona um gerador de números aleatórios, onde ele pode falhar e como as ferramentas deste site escolhem seus resultados.
Dois tipos de acaso
- Números realmente aleatórios vêm de algo físico que ninguém consegue prever: o ruído elétrico em um circuito, o decaimento radioativo, a estática de rádio da atmosfera. O Random.org, por exemplo, usa ruído atmosférico.
- Números pseudoaleatórios vêm de uma fórmula. Você começa com um número chamado semente, passa esse número pela fórmula e obtém o próximo, e depois o seguinte. O resultado parece aleatório, mas a mesma semente sempre gera a mesma sequência.
Pseudoaleatório parece trapaça, mas é o que quase todo jogo, aplicativo e simulação usa. É rápido, e uma boa fórmula passa nos mesmos testes estatísticos em que o acaso verdadeiro passa.
O primeiro método no computador e sua falha
Por volta de 1949, o matemático John von Neumann sugeriu o método do quadrado do meio: eleve um número ao quadrado, pegue os dígitos do meio e repita. Começando com 1234, o quadrado é 01522756, então o próximo número é 5227, depois 3215, 3362, 3030 e assim por diante.
Parece aleatório, mas cai em ciclos. Comece com 2916 e você terá 5030, 3009, 0540, 2916 e, depois, os mesmos quatro números para sempre. Von Neumann sabia disso. Ele usava o método porque era rápido e conferia os resultados em busca de problemas. Segundo sua famosa piada, quem tenta produzir números aleatórios com aritmética está “em estado de pecado”.
Antes dos computadores: livros de números aleatórios
Os cientistas precisavam tanto de números aleatórios que eles chegavam a ser impressos em livros. Em 1955, a RAND Corporation publicou A Million Random Digits with 100,000 Normal Deviates, feito com uma roleta eletrônica. Os pesquisadores abriam uma página ao acaso e iam lendo os dígitos. Muito antes disso, as pessoas usavam dados, moedas e sorteios, como você pode ler no nosso artigo sobre o oráculo dos dados na Antiguidade.
Como funcionam os geradores modernos
Os geradores pseudoaleatórios de hoje são muito melhores. Entre os mais comuns estão:
- Mersenne Twister: o padrão no Python e em muitas outras ferramentas. Ele só se repete depois de 219937 − 1 números, um número com cerca de 6.000 dígitos.
- xorshift128+: o gerador por trás do Math.random() no Chrome e em outros navegadores baseados no motor V8. Muito rápido, bom para jogos e animações.
- Geradores criptográficos: o tipo usado em senhas e chaves de criptografia. O sistema operacional mistura eventos físicos imprevisíveis, como pequenas diferenças de tempo no hardware, para que nem quem conhece a fórmula consiga prever o próximo número.
Geradores comuns servem bem para um jogo. Mas, se alguém vir resultados suficientes deles, às vezes consegue deduzir o resto. Para qualquer coisa em que justiça ou segurança importem, o tipo criptográfico é a escolha certa.
Uma armadilha escondida: o viés do módulo
Mesmo um gerador perfeito pode dar resultados injustos se for usado sem cuidado. Digamos que você tenha um byte aleatório, ou seja, um número de 0 a 255, e queira rolar um dado. O jeito fácil é dividir por 6 e usar o resto. Mas 256 não é divisível por 6, então quatro das faces ganham uma chance a mais:
| Face | Chance |
|---|---|
| 1, 2, 3 ou 4 | 43 em 256 cada (16,8%) |
| 5 ou 6 | 42 em 256 cada (16,4%) |
A diferença é pequena, mas aparece ao longo de milhares de rolagens. A solução é simples: se o número aleatório cair na parte que sobra e não se divide por igual, ele é descartado e outro é sorteado. Isso se chama amostragem por rejeição.
Como nossas ferramentas escolhem
Nossas ferramentas Cara ou coroa, Rolar dados, Número aleatório, Sorteador de nomes e as outras que usam o mesmo código recorrem ao gerador criptográfico do seu navegador, chamado crypto.getRandomValues. Elas também usam amostragem por rejeição, então cada face, número e nome tem exatamente a mesma chance. Navegadores antigos sem esse recurso passam a usar o Math.random(). Tudo roda no seu próprio navegador; nada é decidido no nosso servidor.
Então é aleatório mesmo?
Para jogar uma moeda ou rolar um dado, um bom gerador é melhor que o objeto real. Moedas de verdade têm uma levíssima tendência para o lado com que começam, como explica nosso artigo sobre a probabilidade de cara ou coroa, e dados de verdade podem ser um pouco irregulares. Um bom gerador não tem nenhum desses problemas.
O risco maior está na pessoa que lê os resultados. A gente vê padrões nas sequências e espera que o resultado “que está faltando” esteja para sair. Essa é a falácia do apostador, e ela engana as pessoas com muito mais frequência do que qualquer computador. Para ver como somos ruins em inventar números aleatórios por conta própria, leia “Podemos ser aleatórios?”.
Perguntas frequentes
Um computador consegue gerar números realmente aleatórios?
Não só com uma fórmula. Fórmulas geram números pseudoaleatórios, que apenas parecem aleatórios. Para ter acaso verdadeiro, os computadores medem eventos físicos imprevisíveis, como o ruído elétrico, e muitos aparelhos têm hardware para isso.
O que é a semente de um gerador de números aleatórios?
É o número inicial da fórmula. A mesma semente sempre gera a mesma sequência, o que é útil para testes e para jogos que deixam você compartilhar um mundo ou uma fase pela semente.
O Math.random() é realmente aleatório?
Não. É um gerador pseudoaleatório rápido, bom para jogos, mas não para nada secreto ou em que haja dinheiro em jogo. Para isso, os navegadores oferecem o crypto.getRandomValues.
Cara ou coroa e dados online são justos?
Quando bem feitos, sim. Nossas ferramentas de cara ou coroa e de rolar dados usam o gerador criptográfico do navegador com amostragem por rejeição, então cada resultado tem exatamente a mesma chance.
O que é o viés do módulo?
Uma pequena injustiça que aparece quando você encaixa um número aleatório em um intervalo menor usando o resto de uma divisão e a conta não fecha certinho. A amostragem por rejeição elimina esse viés.