kelvin@cluxnei:~/blog$ cat entropia.md
De onde vem um número aleatório
Construí um site que sorteia coisas usando terremotos, a posição da Estação Espacial, ruído atmosférico e o vácuo quântico. A pergunta óbvia é por quê, já que todo computador tem uma função de aleatório embutida. A resposta envolve entropia, sistemas caóticos, e uma descoberta que costuma surpreender: a aleatoriedade do seu computador já é física, você só não consegue verificar isso.
Neste texto
O que é entropia, de verdade
A palavra carrega duas histórias. Na termodinâmica, entropia mede o quanto a energia de um sistema está espalhada. Na teoria da informação, que é a que interessa aqui, ela mede outra coisa: surpresa.
Claude Shannon formalizou isso em 1948. Se um evento tem probabilidade
p, a surpresa de vê-lo acontecer é log₂(1/p). A
entropia de uma fonte é a surpresa média de tudo que ela pode produzir:
A unidade é o bit. Um bit de entropia é exatamente a incerteza de uma moeda honesta.
Duas consequências que valem guardar.
Entropia não é sobre o valor, é sobre a distribuição. O número 7 não é mais nem menos aleatório que o 4. O que tem ou não tem entropia é o processo que escolheu.
Viés custa bits. Uma moeda honesta dá 1 bit por lançamento. Uma moeda que cai cara em 90% das vezes dá apenas 0,47 bit. Ela ainda é imprevisível, só que menos, e você precisa de mais que o dobro de lançamentos para extrair a mesma quantidade de incerteza.
moeda honesta p = 0,50 1,00 bit por lançamento moeda viciada p = 0,90 0,47 bit por lançamento dado de seis p = 1/6 2,58 bits por rolagem byte pleno 256 valores 8,00 bits
Guarde essa ideia de "bits por evento". Ela é a régua que vai separar, mais adiante, uma fonte que serve de uma fonte que é enfeite.
Por que um computador não sorteia nada
Um processador é uma máquina determinística. Mesma entrada, mesmo estado, mesma saída, sempre. Isso é a coisa mais valiosa que ele tem: é por isso que software funciona. E é exatamente por isso que ele não consegue, sozinho, produzir uma surpresa.
O que a função rand() faz é outra coisa: ela produz uma sequência
que parece aleatória a partir de um estado interno. O nome disso é
gerador pseudoaleatório, e a forma clássica é um congruencial linear:
Cada número é uma função aritmética do anterior. Conhecendo o estado, você conhece toda a sequência, para frente e para trás.
Isso significa que a entropia real de um PRNG é a entropia da semente, e mais nada. Se a semente tem 32 bits, a sequência inteira tem 32 bits de surpresa, não importa se você extrair um milhão de números dela. O gerador não cria incerteza, ele a estica.
Math.random() no navegador e
rand() em C não são criptograficamente seguros, e a documentação
deles diz isso. Observando saídas suficientes dá para reconstruir o estado
interno e prever o resto. Para um jogo da velha, tudo bem. Para sortear qualquer
coisa que importe, não.
Onde o computador arranja entropia de verdade
Aqui está a parte que costuma faltar na conversa, e que é o contrário do que muita gente imagina.
Sistemas operacionais modernos mantêm um pool de entropia, e
o que entra nele não é matemática: é física. Jitter no tempo exato entre
interrupções de hardware. Ruído térmico em circuitos dedicados. Instruções de
CPU como RDRAND, que amostram um oscilador em anel cuja
instabilidade é térmica. O intervalo, em nanossegundos, entre dois pacotes
chegando na placa de rede.
Esse pool alimenta um gerador criptográfico, e o resultado é o que você
recebe ao chamar random_bytes(), /dev/urandom ou
crypto.getRandomValues().
A aleatoriedade "digital" do seu computador já é aleatoriedade do mundo real. Ela só entra por uma porta que você não vê.
E ela é boa. No código do randomly, a fonte que representa o CSPRNG do sistema é classificada como classe A, com este comentário:
/** Full-entropy, unpredictable bytes. Safe to stand alone. */ case Cryptographic = 'A';
Segura para ficar de pé sozinha. Se o objetivo fosse apenas qualidade de entropia, o projeto inteiro seria desnecessário, e seria desonesto fingir o contrário.
Caos: determinístico e imprevisível ao mesmo tempo
Antes de responder por que ir buscar fora, falta uma peça: entender por que um terremoto ou a atmosfera são imprevisíveis, se ambos obedecem a leis físicas perfeitamente determinísticas.
A resposta é caos determinístico. Um sistema caótico é governado por equações exatas, sem nenhuma aleatoriedade dentro, e ainda assim não pode ser previsto a longo prazo. A razão é a sensibilidade às condições iniciais: duas configurações quase idênticas se separam exponencialmente.
Uma diferença inicial δ(0) cresce exponencialmente com o tempo. O expoente λ é o expoente de Lyapunov: quando ele é positivo, o sistema é caótico.
Edward Lorenz tropeçou nisso em 1961, rodando um modelo meteorológico. Ao reiniciar uma simulação a partir do meio, digitou os valores com três casas decimais em vez das seis que a máquina guardava. A previsão resultante divergiu completamente da original. A diferença era de uma parte em mil.
Disso vem a expressão que virou clichê e que quase ninguém sabe que é um enunciado técnico: o efeito borboleta não é uma metáfora poética sobre interconexão, é uma afirmação sobre o crescimento exponencial de erro em sistemas dissipativos não lineares.
A atmosfera é caótica. A crosta terrestre é caótica. O campo geomagnético é caótico. Nenhum deles é aleatório no sentido estrito, mas todos são impraticáveis de prever, porque prever exigiria conhecer o estado atual com precisão infinita.
Então por que ir buscar lá fora
Se o CSPRNG do sistema é seguro, e se as fontes naturais são apenas imprevisíveis na prática, qual é o ponto?
O ponto não é qualidade. É procedência.
Quando um site sorteia um vencedor e diz "foi aleatório", você não tem como
verificar nada. Os bytes vieram de random_bytes(), e essa chamada
não deixa rastro. Não há como distinguir um sorteio honesto de um resultado
escolhido a dedo e apresentado como sorteio. A confiança é integral e cega.
A proposta do randomly é trocar isso por um recibo. Todo resultado sai acompanhado da fonte, do instante, de um relato em linguagem natural e de um link para o dado original, no site de quem o publicou.
valor 9, 23, 8, 47, 12 fonte RANDOM.ORG · classe A relato Ruído atmosférico, amostrado em Dublin momentos atrás prova https://www.random.org/randomness/ instante 2026-09-14T17:31:35+00:00 latência 274 ms
Você pode ir lá conferir. E, mais importante, o resultado inteiro é reproduzível a partir da própria URL: o token carrega o gerador, os parâmetros e a referência da fonte, então qualquer pessoa recalcula exatamente o mesmo sorteio. Não há banco de dados por trás; não há onde adulterar um histórico que não existe.
As três classes, e a que admite ser enfeite
Agora a régua de bits por evento volta a importar. Nem toda fonte do mundo real serve para a mesma coisa, e o código classifica as dez em três categorias:
A · Criptográfica Full-entropy, unpredictable bytes. Safe to stand alone.
CSPRNG do sistema, ANU (vácuo quântico), RANDOM.ORG
B · Pública High entropy at publication, but globally public afterwards.
NIST Beacon, drand, blocos do Bitcoin
C · Observacional Low-rate, biased, structured. Flavour, not entropy.
USGS sísmico, posição da ISS, clima espacial
Repare na classe C. Terremotos, a ISS e o clima espacial são as fontes mais bonitas do projeto, e o comentário no código as chama de sabor, não entropia. Elas produzem pouquíssimos bits por evento, são enviesadas e têm estrutura. A posição da ISS é uma órbita: dá para calcular onde ela vai estar.
Por isso existe uma regra, de uma linha, que governa o sistema inteiro:
mixedWithCsprng: ! $isCsprng
Tudo que não é o próprio CSPRNG é misturado com ele. O
terremoto escolhe qual dos resultados possíveis você vai receber. O CSPRNG
garante que ninguém consiga prever ou reproduzir essa escolha sem o token. E
cada recibo carrega o campo mixed_with_csprng dizendo exatamente
isso, em vez de vender misticismo.
Há outro campo que merece atenção, degraded. Enquanto eu
preparava este texto, um dos exemplos voltou assim:
valor 09 15 33 41 56 57 fonte Operating System CSPRNG · classe A relato Drawn from the kernel entropy pool on the server degraded true
A fonte que eu pedi não respondeu, e o sistema caiu para o CSPRNG local. Ele continuou funcionando e anunciou a queda no recibo, em vez de entregar um resultado com a narrativa bonita de um terremoto que não aconteceu. Essa é a diferença entre degradar e mentir.
Sustentar isso com dez serviços de terceiros exige um disjuntor. Três falhas consecutivas abrem o circuito de uma fonte por sessenta segundos, e a próxima tentativa é uma sondagem que restaura ou reabre. O comentário no código resume o objetivo melhor do que eu resumiria:
Keeps one flaky third party from becoming our outage.
O que dá para fazer com isso
São 63 geradores em seis módulos: números, palavras, equações, padrões, imagens e som. Tudo abaixo é resultado real, puxado da API ao vivo enquanto eu escrevia, cada um semeado por uma fonte diferente.
E fora das imagens, o mesmo mecanismo produz coisas como estas, que eu capturei junto com seus recibos:
frase-senha helper-opossum-lion-safehouse-sensitive-washable
ISS Position · classe C · sobre 40,69° N, 66,82° E
equação 2x² + 4x = 0 → x = -2 ou x = 0
USGS · sismo de magnitude 2,2 a 40 km ESE de Malaga, NM
dados 9, 12, 10, 10, 14, 18
NOAA · índice K planetário 1,67, campo geomagnético quieto
O resumo
Entropia é surpresa, medida em bits. Um computador determinístico não fabrica surpresa: ele estica a que recebeu. A surpresa que ele recebe já vem do mundo físico, por sensores que você não enxerga. E sistemas caóticos são imprevisíveis não por serem aleatórios, mas por amplificarem qualquer incerteza exponencialmente.
Nada disso torna o random_bytes() ruim. O que ele não tem é
recibo. Foi isso que eu fui construir: não uma aleatoriedade
melhor, mas uma que você possa conferir, incluindo a parte em que ela admite ter
sido ajudada.
O randomly está em randomly.cluxnei.dev, com 63 geradores, dez fontes e nenhuma chave de API. Todo resultado é reproduzível pela própria URL. O código está no GitHub.
kelvin@cluxnei:~/blog$