Como refazer tudo
Os números deste site foram calculados por programas escritos por uma inteligência artificial (Claude, da Anthropic). Para não depender de confiar nela, qualquer pessoa pode baixar os mesmos arquivos públicos do TSE e rodar os mesmos programas.
Todos os dados vêm do TSE: os pacotes de cada urna em cdn.tse.jus.br/estatistica/sead/eleicoes/eleicoes<ano>/arqurnatot/ (BU, RDV, imagem do BU, log e arquivo de assinatura de cada seção) e o resultado oficial em resultados.tse.jus.br. Os programas ficam na pasta pipeline/ e são em Python.
Os programas leem só os pedaços necessários de cada pacote, pela internet (HTTP Range); não é preciso baixar os pacotes inteiros, que são grandes (só o de Roraima, no 1º turno de 2022, tem 186 MB).
1. O que instalar
- Python 3.12 (foi usado o 3.12.10, no Windows).
- Bibliotecas:
pip install duckdb pandas numpy pyarrow py7zr(versões usadas: duckdb 2.0.0, pandas 3.1.0, numpy 2.5.4, pyarrow 26.0.0, py7zr 1.1.4). - A verificação da assinatura (curvas Ed521 e P-521) foi escrita do zero em
pipeline/ed521.pyepipeline/p521.py, sem biblioteca de criptografia, para qualquer um poder ler o que é conferido.
2. Passo a passo
Rode os comandos dentro da pasta do projeto. Cada um pode ser interrompido e retomado: o que já foi feito é pulado. Nos comandos com <UF>, rode para cada UF (ou liste várias de uma vez).
Logs das urnas (horários)
python -m pipeline.download 2026 2022
python -m pipeline.rele_logs 2026 1
python -m pipeline.rele_logs 2026 2
Baixa os pacotes, guarda um resumo do log de cada seção (votos por hora e por meia hora, tipo de liberação do eleitor) em build/logs_<ano>_<turno>t_<UF>.parquet e apaga o pacote. O rele_logs relê só os logs, já com as correções (o log do 2º turno traz também o dia do 1º, que é descartado).
BU do 2º turno de 2026
python -m pipeline.bu_remoto 2026 2 <UF>
O TSE ainda não publicou o CSV do BU do 2º turno de 2026; este programa lê o BU binário de cada seção. Ele foi conferido contra o CSV oficial em 2022 e no 1º turno de 2026 (python -m pipeline.valida_remoto). Os BUs em CSV (1º turno de 2026 e 2022) ficam em data/parquet/, convertidos do CSV oficial do TSE (esse conversor não está em pipeline/).
Assinatura digital de cada urna
python -m pipeline.verifica_assinatura 2026 1 AC AL AM AP BA CE DF ES GO MA MG MS MT PA PB PE PI PR RJ RN RO RR RS SC SE SP TO ZZ
python -m pipeline.verifica_assinatura 2026 2 AC AL ... ZZ
python -m pipeline.verifica_assinatura 2022 1 AC AL ... ZZ
python -m pipeline.verifica_assinatura 2022 2 AC AL ... ZZ
Para cada seção: confere a assinatura da urna, se o BU, o RDV e a imagem do BU publicados são os mesmos que a urna assinou, e se o certificado é da urna que aparece no BU. Levou de 1h30 a 3h por turno. Resultado em build/assinatura_<ano>_<turno>t_<UF>.parquet.
Recontagem dos votos pelo RDV
python -m pipeline.rdv 2026 1
python -m pipeline.rdv 2026 2
python -m pipeline.rdv 2022 1
python -m pipeline.rdv 2022 2
O RDV (registro digital do voto) guarda cada voto, um por um, em ordem embaralhada e sem horário (para não identificar o eleitor). O programa conta os votos para presidente de cada seção. Resultado em build/rdv_<ano>_<turno>t_<UF>.parquet.
Total oficial
python -m pipeline.compara_totais 2026 2 6258
Soma os BUs e compara com o total publicado em resultados.tse.jus.br (6258 é o código da eleição do 2º turno de 2026).
Juntar tudo e gerar o site
python -m pipeline.atualiza
python site/server.py 8770
O atualiza junta BU e log por seção e gera todos os arquivos em site/data/: comparação entre turnos, perdas de votos e comparecimento, origem dos votos por urna, assinaturas, checagens de consistência, recontagem pelo RDV e votos por meia hora. Depois, abra http://localhost:8770.
Testes: python -m pytest tests.
3. Onde cada número da página de conclusões é calculado
| Parte | Programa | Arquivo gerado |
|---|---|---|
| Assinatura digital e mesma chave nos dois turnos | verifica_assinatura.py, compara_certificados.py | assinatura_<ano>.json |
| Soma dos BUs = resultado oficial | compara_totais.py | totais_tse_2026_2t.json |
| Recontagem pelo RDV | rdv.py, compara_rdv.py | rdv_<ano>.json |
| Os dados batem entre si? | consistencia.py | consistencia_<ano>.json |
| Votos de meia em meia hora | parse_logs.py, meia_hora.py | meia_hora.json |
| O que mudou entre os turnos, horários, outros | analise.py, zerados.py | conclusoes_<ano>.json, zerados_<ano>.json |
| De onde vieram os votos (estimativa por candidato do 1º turno) | transferencia.py | transferencia_<ano>.json |
| Perdas de votos e comparecimento, quem ficou à frente, 2022 × 2026 | movimentos.py | movimentos_<ano>.json, comparecimento_caiu_<ano>.csv, b_perdeu_municipios_<ano>.csv |
| Origem dos votos por urna (outros candidatos, brancos e nulos, abstenção) | estimativa_urna.py | estimativa_<ano>.json, estimativa_urna_<ano>.csv |
4. Como conferir uma seção sozinho
- Na página Tabela, escolha a UF e o município e ache a zona e a seção na lista.
- No site do TSE, abra o boletim dessa seção e compare os votos.
- Se você tiver uma foto do BU impresso na porta da seção, compare também: o papel é impresso antes de qualquer transmissão.
5. O que não foi conferido
- A assinatura do certificado de cada urna pela autoridade certificadora da Justiça Eleitoral: o certificado raiz não está publicado em local acessível.
- O bloco de assinatura por software (algoritmo CEPESC), que não pode ser verificado com ferramentas públicas.
- O programa da urna em si: a assinatura prova que os arquivos não mudaram depois de gerados, não que a contagem dentro da urna estava certa.