Pular para o conteúdo
Todos os conceitos

Semente de números pseudoaleatórios

O computador não sorteia de verdade. A partir da mesma semente, o gerador repete sempre a mesma sequência.

Um computador não joga dados. O que as linguagens chamam de "aleatório" é um gerador pseudoaleatório: uma conta que, a partir de um número inicial, a semente (seed), produz uma sequência que parece sorteada. Mesma semente, mesma sequência, sempre.

Em Python:

>>> import random
>>> random.seed(10); [random.randint(1, 13) for _ in range(5)]
[10, 1, 7, 8, 10]
>>> random.seed(10); [random.randint(1, 13) for _ in range(5)]
[10, 1, 7, 8, 10]

Em C, no Linux, é igual com srand(semente) e rand(). Depois de srand(1), o primeiro rand() da biblioteca C do Linux (glibc) é sempre 1804289383. Para repetir esses números sem escrever C, o Python chama a própria biblioteca do sistema:

import ctypes
libc = ctypes.CDLL("libc.so.6")   # só no Linux (ou WSL)
libc.srand(1)
print(libc.rand())                 # 1804289383

Isso vira falha de segurança quando o número sorteado protege alguma coisa (uma senha temporária, um token, uma chave) e a semente pode ser descoberta: um valor fixo no código, o horário em que o programa começou, o número do processo. Quem acha a semente recalcula todos os "sorteios". Para segredos, use um gerador criptográfico: em Python, o módulo secrets.

o programa sorteia random.seed(10) gerador uma conta fixa 10 1 7 8 10 = = = = = quem descobre a semente refaz os sorteios random.seed(10) gerador uma conta fixa 10 1 7 8 10 mesma semente, mesma sequência
Com a semente 10, o gerador sempre dá 10, 1, 7, 8, 10: quem descobre a semente refaz exatamente os mesmos sorteios do programa.

Em engenharia reversa, a pergunta é sempre a mesma: qual semente vale na hora do sorteio? Procure as chamadas a seed/srand, veja com que valor e em que ordem acontecem, e reproduza a sequência.

Aparece nestes desafios