Como conferir o resultado por conta própria
Você não precisa confiar na plataforma nem no organizador. Esta página explica o que conferir e como.
O que é publicado, e quando
Passo 1: a lista é a mesma?
Baixe o CSV da lista congelada na página de resultado e recalcule o hash. Se bater com o hash publicado antes do sorteio, a lista é a mesma que foi congelada.
import crypto from 'node:crypto'
import fs from 'node:fs'
// linhas do CSV baixado, sem o cabeçalho
const linhas = fs.readFileSync('lista-congelada.csv', 'utf8')
.trim().split('\n').slice(1)
.map(l => { const [number, order_code] = l.split(','); return { number, order_code } })
function hashDaLista(linhas) {
const ordenadas = [...linhas].sort((a, b) => Number(a.number) - Number(b.number))
const blocos = []
for (let i = 0; i < ordenadas.length; i += 100000) {
const bloco = ordenadas.slice(i, i + 100000)
.map(l => `${l.number}:${l.order_code}`).join(',')
blocos.push(crypto.createHash('md5').update(bloco).digest('hex'))
}
if (blocos.length === 0) return crypto.createHash('md5').update('vazio').digest('hex')
return crypto.createHash('md5').update(blocos.join('')).digest('hex')
}
console.log(hashDaLista(linhas))Sorteio eletrônico, passo 2: a semente é a que foi comprometida?
O SHA-256 da semente revelada tem que ser igual ao compromisso publicado antes do sorteio.
crypto.createHash('sha256').update(semente, 'utf8').digest('hex') === compromissoSorteio eletrônico, passo 3: qual número sai dessa conta?
O índice vem do MD5 de três partes juntadas por dois-pontos: o hash da lista, a semente e a entropia. Dos 32 dígitos hexadecimais do MD5, entram os quinze primeiros, lidos como um inteiro, e o resto da divisão pela quantidade de números pagos dá o índice. A lista em ordem crescente, naquele índice, é o vencedor.
const md5 = crypto.createHash('md5')
.update(`${hashDaLista}:${semente}:${entropia}`).digest('hex')
// quinze dígitos hexadecimais, como inteiro de 60 bits
const indice = Number(BigInt('0x' + md5.slice(0, 15)) % BigInt(elegiveis))
const ordenadas = [...linhas].sort((a, b) => Number(a.number) - Number(b.number))
console.log('vencedor:', ordenadas[indice].number)O corte em quinze dígitos não é detalhe de implementação que dá para ignorar: com os 32 dígitos inteiros o resto da divisão é outro, e você chegaria a outro número. É assim que o banco de dados calcula, e é assim que a conta tem que ser refeita.
Loteria Federal e semente publicada: a conta tem DUAS partes
Nestes dois métodos não existe semente secreta nem compromisso: a semente vem de fora e é pública desde o começo. Por isso a conta junta duas partes, não três, e usar a fórmula do eletrônico aqui leva a outro número.
const md5 = crypto.createHash('md5')
.update(`${hashDaLista}:${semente}`).digest('hex')
const indice = Number(BigInt('0x' + md5.slice(0, 15)) % BigInt(elegiveis))
const ordenadas = [...linhas].sort((a, b) => Number(a.number) - Number(b.number))
console.log('vencedor:', ordenadas[indice].number)A semente é o valor que a página de resultado publica: no caso da Loteria Federal, os números da extração posterior ao congelamento da lista, transcritos exatamente como estão na fonte oficial. Confira a transcrição na fonte antes de refazer a conta: um caractere diferente dá outro vencedor.
Sorteio presencial no globo: não existe conta, e isso é o ponto
No globo o acaso acontece na frente de quem está no evento, e a plateia confere com os olhos. Não há semente, não há entropia e não há nada para recalcular. O que a plataforma garante aqui é outra coisa, e ela também é conferível:
Por que isso fecha os dois lados
Vale para o sorteio eletrônico, que é o método em que a plataforma participa da geração do acaso.
Achou divergência? Guarde o CSV e os valores da página e fale com o organizador da campanha. A página de resultado refaz essa conta sozinha e avisa quando ela não fecha.
Voltar