bateCarimbo.
Eleitoral

Título de eleitor: estrutura do número, código da UF, zona e seção — e a exceção de SP e MG

Os doze dígitos do título explicados: sequencial, código da unidade federativa e os dois dígitos verificadores. Tabela completa dos códigos por estado, cálculo resolvido e a exceção do TSE que faz São Paulo e Minas Gerais divergirem.

Por · Publicado em · 10 min de leitura

O número do título de eleitor quase sempre aparece em três blocos de quatro dígitos — 1234 5678 2097 — e esse agrupamento não corresponde aos campos internos do número. Os campos têm oito, dois e dois dígitos. O último bloco impresso mistura o código da unidade federativa com os dois dígitos verificadores, o que é suficiente para quebrar qualquer parser escrito olhando apenas para a máscara.

Anatomia dos doze dígitos

São doze algarismos decimais, sem letras e sem separador obrigatório. A divisão é fixa:

  • Posições 1 a 8 — sequencial de inscrição atribuído pela Justiça Eleitoral no alistamento. Não há data, faixa etária nem código de município embutidos: é um contador, e nada nele é decodificável.
  • Posições 9 e 10 — código da unidade federativa vinculada à inscrição, de 01 a 28.
  • Posições 11 e 12 — dígitos verificadores calculados por módulo 11, cada um com uma regra diferente.

O sequencial pode começar com zero, e o código de UF de São Paulo é literalmente 01. Guardar o título como inteiro perde esses zeros e transforma um número válido em um número de onze dígitos que nenhum validador aceita. A coluna correta é textual e de tamanho fixo: char(12) ou varchar(12), com a máscara aplicada só na exibição. A normalização é a de sempre — remover pontos, hífens e espaços, conferir que sobraram doze dígitos e validar sobre a forma limpa. Um padrão pronto para isso está no guia de regex para documentos brasileiros.

A tabela completa dos códigos por unidade federativa

São 28 códigos: os 27 entes federativos mais o código 28, usado por inscrições do exterior e normalmente exibido como ZZ. A ordem não é alfabética nem a numeração do IBGE — é uma sequência própria da Justiça Eleitoral, que começa por São Paulo e Minas Gerais. Qualquer par fora da faixa 01–28, incluindo 00, invalida o número antes mesmo do cálculo do dígito.

Códigos de UF nos dígitos 9–10, com um título de exemplo para cada um (todos derivados do sequencial 12345678).
CódigoUnidade federativaExemplo
01São Paulo (SP)1234 5678 0191
02Minas Gerais (MG)1234 5678 0299
03Rio de Janeiro (RJ)1234 5678 0396
04Rio Grande do Sul (RS)1234 5678 0493
05Bahia (BA)1234 5678 0590
06Paraná (PR)1234 5678 0698
07Ceará (CE)1234 5678 0795
08Pernambuco (PE)1234 5678 0892
09Santa Catarina (SC)1234 5678 0990
10Goiás (GO)1234 5678 1090
11Maranhão (MA)1234 5678 1198
12Paraíba (PB)1234 5678 1295
13Pará (PA)1234 5678 1392
14Espírito Santo (ES)1234 5678 1490
15Piauí (PI)1234 5678 1597
16Rio Grande do Norte (RN)1234 5678 1694
17Alagoas (AL)1234 5678 1791
18Mato Grosso (MT)1234 5678 1899
19Mato Grosso do Sul (MS)1234 5678 1996
20Distrito Federal (DF)1234 5678 2097
21Sergipe (SE)1234 5678 2194
22Amazonas (AM)1234 5678 2291
23Rondônia (RO)1234 5678 2399
24Acre (AC)1234 5678 2496
25Amapá (AP)1234 5678 2593
26Roraima (RR)1234 5678 2690
27Tocantins (TO)1234 5678 2798
28Exterior (ZZ)1234 5678 2895

Repare na coluna de exemplos: o primeiro dígito verificador é 9 nos 28 casos. Isso não é coincidência nem erro da tabela — é consequência direta do algoritmo, que calcula o primeiro dígito apenas sobre o sequencial. Trocar a UF muda somente o segundo.

Zona e seção não estão no número

A confusão nasce do documento físico, onde o número da inscrição, a zona e a seção são impressos lado a lado, no mesmo bloco visual. Muita gente conclui que o terceiro grupo de quatro dígitos é a zona. Não é: nos doze dígitos não existe campo de zona nem de seção, e nenhuma operação aritmética sobre eles recupera essa informação.

Zona e seção descrevem onde a pessoa vota. A zona é a circunscrição da Justiça Eleitoral que administra o eleitorado de uma área, com seu cartório; a seção é o agrupamento menor, associado a um local e a uma mesa de votação. São atributos da situação eleitoral corrente, consultáveis nos serviços do TSE, e mudam com transferências e com a reorganização dos locais de votação — sem que isso esteja refletido nos doze dígitos.

Na modelagem, isso significa três campos independentes: titulo, zona e secao. Derivar os dois últimos do primeiro é impossível, e formulários que pedem zona e seção junto com o número estão pedindo dados que só vêm da consulta oficial ou do próprio eleitor.

O cálculo dos dois dígitos verificadores, resolvido

O título usa módulo 11 em dois estágios, e o segundo estágio é incomum: ele não percorre o número inteiro. O primeiro dígito sai dos oito algarismos do sequencial, com pesos crescentes de 2 a 9. Tomando o sequencial 12345678 e o Distrito Federal (20):

Primeiro dígito verificador — pesos 2 a 9 sobre o sequencial
CaracterePesoProduto
122
236
3412
4520
5630
6742
7856
8972
Soma240

240 ÷ 11 → resto 9

O resto é o próprio dígito (só o resto 10 recebe tratamento especial).

Dígito verificador = 9

O segundo dígito opera sobre apenas três valores: os dois algarismos do código da UF e o primeiro dígito recém-calculado, com pesos 7, 8 e 9. O sequencial não entra nessa conta.

Segundo dígito verificador — pesos 7, 8 e 9 sobre UF e 1º DV
CaracterePesoProduto
2714
080
9981
Soma95

95 ÷ 11 → resto 7

O resto é o próprio dígito.

Dígito verificador = 7

Juntando tudo: 12345678 + 20 + 97 = 1234 5678 2097. Quando o resto de qualquer um dos dois estágios é 10, o dígito vira 0. É o caso de 1000 0007 0302, do Rio de Janeiro: a soma do sequencial dá 65, o resto é 10 e o primeiro dígito vira 0; o segundo estágio soma 0×7 + 3×8 + 0×9 = 24, resto 2.

A consequência prática dessa estrutura é que o segundo dígito é função exclusiva do par (código da UF, primeiro dígito). São no máximo 280 combinações de entrada, o que permite substituir o segundo estágio por uma tabela pré-calculada quando a validação é feita em volume — e explica por que o dígito verificador do título detecta bem erros de digitação, mas serve de muito pouco como evidência de que o número existe. A ideia geral do algoritmo está no guia de módulo 11.

A exceção de São Paulo e Minas Gerais

Nos títulos emitidos em São Paulo (01) e Minas Gerais (02), o resto 0 não produz o dígito 0: produz o dígito 1. A regra vale para os dois estágios do cálculo, e é a única diferença de tratamento por estado em todo o algoritmo.

O sequencial 11111111 mostra o efeito. A soma ponderada dá 1×(2+3+4+5+6+7+8+9) = 44, e 44 é divisível por 11 — resto 0. Em qualquer outro estado o primeiro dígito seria 0. Em São Paulo ele é 1, e o segundo estágio passa a somar 0×7 + 1×8 + 1×9 = 17, resto 6: o título é 1111 1111 0116. O mesmo sequencial em Minas Gerais soma 0×7 + 2×8 + 1×9 = 25, resto 3, gerando 1111 1111 0213.

Fora desses dois códigos, o resto 0 continua valendo 0, e isso aparece na massa de teste mais abaixo: 6021 9483 2003, do Distrito Federal, tem resto 0 no primeiro estágio e primeiro dígito 0. 4801 2377 0620, do Paraná, tem resto 0 no segundo estágio e segundo dígito 0. Nenhum dos dois seria escrito assim se a UF fosse 01 ou 02.

Por que dois validadores discordam do mesmo título

Boa parte das implementações que circulam por aí ignora a exceção de SP/MG. Para essas, o sequencial 11111111 em São Paulo produz 1111 1111 0108, e não 1111 1111 0116. Os dois números não podem estar certos ao mesmo tempo: cada validador aceita o seu e rejeita o do outro. Quando um cadastro reclama que um título "válido no outro sistema" foi recusado, é aqui que se deve olhar primeiro.

A divergência só acontece quando algum dos dois restos dá 0 em um título de SP ou MG. É um subconjunto pequeno e perfeitamente identificável, então dá para calcular os dígitos nas duas interpretações e comparar:

TypeScript
const SP_MG = new Set(["01", "02"]);

function applyRest(rest: number, ufCode: string, withException: boolean): number {
  if (rest === 10) return 0;
  if (withException && rest === 0 && SP_MG.has(ufCode)) return 1;
  return rest;
}

function checkDigits(seq8: string, ufCode: string, withException: boolean): string {
  let sum1 = 0;
  for (let i = 0; i < 8; i++) {
    sum1 += Number(seq8[i]) * (i + 2);
  }
  const dv1 = applyRest(sum1 % 11, ufCode, withException);

  const sum2 = Number(ufCode[0]) * 7 + Number(ufCode[1]) * 8 + dv1 * 9;
  const dv2 = applyRest(sum2 % 11, ufCode, withException);

  return String(dv1) + String(dv2);
}

/** Sequenciais de SP/MG em que as duas interpretações divergem. */
function isContestedBase(seq8: string, ufCode: string): boolean {
  if (!SP_MG.has(ufCode)) return false;
  return checkDigits(seq8, ufCode, true) !== checkDigits(seq8, ufCode, false);
}
Implementação usada pelo gerador. O parâmetro withException permite reproduzir as duas leituras da regra.

O gerador de título descarta os sequenciais em que isContestedBase retorna verdadeiro. Números gerados por ele passam nas duas leituras da regra, o que evita que uma massa de teste falhe por causa de uma decisão de implementação de terceiros em vez de um defeito real. Para testar a exceção de propósito, o caminho é o contrário: use justamente um sequencial ambíguo e fixe qual interpretação o seu sistema adota.

O que o número não prova

Dígitos verificadores corretos dizem que a sequência é bem formada, e só. Não dizem que a inscrição existe, que está regular, que não há pendências, nem se a pessoa é obrigada a votar. Essa informação vem dos serviços do TSE, não da aritmética — a mesma distinção entre forma e existência que vale para o CPF e está detalhada em válido não é o mesmo que existente.

O código de UF também é frequentemente superinterpretado. Ele identifica a unidade federativa vinculada à inscrição, não o estado de nascimento, não o endereço atual e não o local onde a pessoa vota hoje. Usar esse par de dígitos como filtro de domicílio em regra de negócio produz falsos negativos silenciosos, do mesmo tipo que a leitura da região fiscal do CPF costuma provocar.

Números reais de título são dado pessoal e vinculam identidade civil a exercício político, o que os coloca entre os campos que menos convém arrastar para bancos de homologação. A alternativa, aqui e nos demais documentos, é massa fictícia com dígito válido — o guia sobre LGPD e dados de teste trata do porquê.

Massa de teste por estado

Os títulos abaixo têm sequenciais variados, cobrem os casos-limite do algoritmo e foram conferidos contra a implementação do site. Nenhum deles é ambíguo, então servem tanto para validadores que aplicam a exceção de SP/MG quanto para os que não aplicam.

Títulos fictícios para fixtures. A terceira coluna indica o caso-limite exercitado.
UFTítuloO que exercita
SP (01)2468 0135 0124resto 2 no 1º DV, resto 4 no 2º
MG (02)9182 7364 0213resto 1 no 1º DV — a exceção não se aplica
RJ (03)5550 0012 0353sequencial com zeros no meio
RJ (03)1000 0007 0302resto 10 no 1º DV, que vira 0
RS (04)3321 0987 0493mesmo par de DV do exemplo 1234 5678 0493
BA (05)7065 4321 0515—
PR (06)4801 2377 0620resto 0 no 2º DV, que permanece 0 fora de SP/MG
SC (09)8237 0145 0906resto 10 no 1º DV
DF (20)6021 9483 2003resto 0 no 1º DV, que permanece 0 fora de SP/MG
AM (22)1739 5028 2208sequencial idêntico ao anterior em soma

Para gerar os seus em vez de copiar os de cima, vale fixar o sequencial e variar a UF — a massa fica determinística e o teste não depende de aleatoriedade:

TypeScript
const UF_CODES = ["01", "03", "06", "20", "26"];
const SEQ = "12345678";

export const TITULOS_FIXTURE = UF_CODES.map(
  (uf) => SEQ + uf + checkDigits(SEQ, uf, true),
);
// ["123456780191", "123456780396", "123456780698", ...]
Um título por estado, sempre os mesmos entre execuções.

Quando o volume é maior, ou quando você precisa de títulos de uma UF específica já formatados em blocos de quatro, o gerador de título de eleitor faz isso em lote e valida números existentes na mesma tela, mostrando a UF detectada nos dígitos 9 e 10.

Fontes e referências