Documentos brasileiros9 min de leitura

Como funciona o dígito verificador do CPF (módulo 11, passo a passo)

O cálculo dos dois dígitos verificadores do CPF explicado número a número, com implementação em JavaScript e Python, casos-limite que quebram validadores e o que a validação sintática realmente prova.

Publicado em

AL

Por André Leitão

Desenvolvedor de software

Todo formulário brasileiro que pede CPF acaba precisando responder a mesma pergunta: esse número é plausível? A resposta está nos dois últimos dígitos do documento, chamados dígitos verificadores. Eles não são aleatórios — são calculados a partir dos nove primeiros por uma variação do módulo 11. Entender esse cálculo é a diferença entre confiar cegamente numa biblioteca e saber por que uma entrada foi recusada.

Este artigo destrincha o algoritmo dígito a dígito, mostra implementações em JavaScript e Python, lista os casos-limite que costumam passar despercebidos em produção e, mais importante, deixa claro o que a validação sintática não prova.

A estrutura dos onze dígitos

Um CPF tem onze dígitos, normalmente escritos como 000.000.000-00. Os oito primeiros formam o número base da inscrição. O nono identifica a região fiscal onde o documento foi emitido. Os dois últimos são os verificadores, calculados sobre tudo que vem antes.

Regiões fiscais indicadas pelo nono dígito
DígitoRegião fiscalEstados
01ª regiãoDF, GO, MS, MT e TO
11ª regiãoDF, GO, MS, MT e TO
22ª regiãoAC, AM, AP, PA, RO e RR
33ª regiãoCE, MA e PI
44ª regiãoAL, PB, PE e RN
55ª regiãoBA e SE
66ª regiãoMG
77ª regiãoES e RJ
88ª regiãoSP
99ª regiãoPR e SC

O cálculo do primeiro dígito verificador

O primeiro verificador usa os nove primeiros dígitos. Cada um é multiplicado por um peso decrescente que começa em 10 e termina em 2. Os produtos são somados, a soma é multiplicada por 10 e o resto da divisão por 11 é o dígito — com uma exceção: se o resto for 10, o dígito é 0.

Vamos acompanhar com o CPF fictício 529.982.247-25, que é o exemplo mais usado em documentação técnica justamente por não ser uma sequência repetida. Os nove primeiros dígitos são 5, 2, 9, 9, 8, 2, 2, 4 e 7.

Primeiro dígito: pesos de 10 a 2
DígitoPesoProduto
51050
2918
9872
9763
8648
2510
248
4312
7214
Soma295

A soma é 295. Multiplicando por 10 chegamos a 2950. O resto de 2950 dividido por 11 é 2. Como o resto é menor que 10, o primeiro dígito verificador é 2 — exatamente o que aparece no documento.

O cálculo do segundo dígito verificador

O segundo verificador repete a mecânica, com duas diferenças: ele considera dez dígitos (os nove originais mais o primeiro verificador que acabamos de calcular) e os pesos começam em 11 em vez de 10.

Segundo dígito: pesos de 11 a 2
DígitoPesoProduto
51155
21020
9981
9872
8756
2612
2510
4416
7321
224
Soma347

347 multiplicado por 10 é 3470, e o resto da divisão por 11 é 5. O segundo dígito verificador é 5. O documento fecha como 529.982.247-25.

Implementação em JavaScript

A implementação abaixo isola o cálculo de um dígito em uma função auxiliar, o que evita duplicar a lógica e deixa o caso do resto 10 num único lugar.

Validação completa de CPF em JavaScript
function calcularDigito(digitos, pesoInicial) {
  const soma = digitos.reduce(
    (acc, digito, indice) => acc + digito * (pesoInicial - indice),
    0
  );
  const resto = (soma * 10) % 11;
  return resto === 10 ? 0 : resto;
}

export function validarCpf(entrada) {
  const digitos = String(entrada).replace(/\D/g, "");

  if (digitos.length !== 11) return false;
  // Sequências repetidas satisfazem a fórmula, mas não são documentos válidos.
  if (/^(\d)\1{10}$/.test(digitos)) return false;

  const numeros = digitos.split("").map(Number);
  const base = numeros.slice(0, 9);

  const primeiro = calcularDigito(base, 10);
  if (primeiro !== numeros[9]) return false;

  const segundo = calcularDigito([...base, primeiro], 11);
  return segundo === numeros[10];
}

Implementação em Python

A mesma lógica, agora em Python
import re


def calcular_digito(digitos, peso_inicial):
    soma = sum(d * (peso_inicial - i) for i, d in enumerate(digitos))
    resto = (soma * 10) % 11
    return 0 if resto == 10 else resto


def validar_cpf(entrada: str) -> bool:
    digitos = re.sub(r"\D", "", str(entrada))

    if len(digitos) != 11:
        return False
    if digitos == digitos[0] * 11:
        return False

    numeros = [int(c) for c in digitos]
    base = numeros[:9]

    primeiro = calcular_digito(base, 10)
    if primeiro != numeros[9]:
        return False

    segundo = calcular_digito(base + [primeiro], 11)
    return segundo == numeros[10]

Casos-limite que derrubam validadores em produção

O algoritmo em si é curto. O que costuma quebrar são as bordas — entradas que chegam de formulários, planilhas, integrações e leitores de documento em formatos que o desenvolvedor não previu.

  1. 1Sequências repetidas. De 000.000.000-00 a 999.999.999-99, todas passam no módulo 11. Rejeite-as explicitamente antes de calcular, como no exemplo acima.
  2. 2Zeros à esquerda perdidos. Um CPF lido de planilha como número vira 12345678 em vez de 00012345678. Trate CPF sempre como texto, do parser ao banco.
  3. 3Pontuação inconsistente. A mesma pessoa pode chegar como 529.982.247-25, 529982247-25 ou 52998224725. Normalize para dígitos puros antes de comparar ou gravar.
  4. 4Espaços invisíveis. Colagem de PDF costuma trazer espaço não separável (U+00A0). Um replace que só remove \\D resolve, mas um trim simples não.
  5. 5Tamanho maior que onze. Concatenações acidentais geram doze ou treze dígitos; validar o tamanho depois de limpar evita índices fora do intervalo.
  6. 6Entrada nula ou indefinida. Converter para texto antes de aplicar a expressão regular impede exceção em campo opcional não preenchido.

O que a validação sintática realmente prova

Esta é a parte mais mal compreendida do assunto. Passar no módulo 11 significa apenas que os onze dígitos são coerentes entre si. Não significa que a inscrição existe, que está ativa, que pertence a quem preencheu o formulário nem que o titular é maior de idade.

O que cada camada de verificação responde
CamadaPergunta respondidaOnde roda
Máscara e tamanhoO campo tem o formato esperado?Frontend
Módulo 11Os dígitos são internamente consistentes?Frontend e backend
Consulta cadastralA inscrição existe e está regular?Serviço oficial autorizado
Verificação de identidadeQuem preencheu é o titular?Provedor de KYC ou processo próprio

Confundir a segunda linha com a quarta é o erro que leva sistemas a aceitarem cadastros fraudulentos achando que estão protegidos. Validação sintática é filtro de digitação, não controle antifraude.

Gerando CPFs para teste sem usar dados reais

Justamente porque o algoritmo é determinístico, é trivial gerar números que passam nele. Isso resolve um problema real de equipes de desenvolvimento e QA: preencher massa de teste sem copiar documentos de pessoas físicas para bases de homologação, o que criaria uma exposição desnecessária sob a LGPD.

A geração é o caminho inverso da validação: sorteia-se os nove primeiros dígitos e calcula-se os dois verificadores com as mesmas funções. É exatamente o que o gerador de CPF do Codigio Labs faz, inteiramente no navegador — nenhum número gerado é enviado a um servidor.

Uma suíte de testes mínima

Se você acabou de escrever seu validador, estes seis casos cobrem quase todo o espaço de falha comum:

Casos que qualquer validador de CPF deveria passar
describe("validarCpf", () => {
  it("aceita CPF válido com pontuação", () => {
    expect(validarCpf("529.982.247-25")).toBe(true);
  });

  it("aceita CPF válido sem pontuação", () => {
    expect(validarCpf("52998224725")).toBe(true);
  });

  it("rejeita dígito verificador incorreto", () => {
    expect(validarCpf("529.982.247-26")).toBe(false);
  });

  it("rejeita sequência repetida", () => {
    expect(validarCpf("111.111.111-11")).toBe(false);
  });

  it("rejeita tamanho diferente de onze dígitos", () => {
    expect(validarCpf("5299822472")).toBe(false);
  });

  it("não lança exceção com entrada vazia ou nula", () => {
    expect(validarCpf("")).toBe(false);
    expect(validarCpf(null)).toBe(false);
  });
});

Resumo

  • Os dois dígitos finais do CPF vêm de um módulo 11 sobre os dígitos anteriores, com pesos decrescentes a partir de 10 e de 11.
  • Resto igual a 10 vira dígito 0 — é o caso-limite mais esquecido em implementações caseiras.
  • Sequências repetidas passam na fórmula e precisam de rejeição explícita.
  • Armazene sempre os onze dígitos sem pontuação e formate apenas na exibição.
  • Validação sintática filtra erro de digitação; ela não confirma existência, titularidade nem regularidade da inscrição.

Perguntas frequentes

Um CPF que passa na validação matemática existe de verdade?
Não. O cálculo do módulo 11 só prova que os onze dígitos são internamente consistentes. Existem cerca de um bilhão de combinações estruturalmente válidas, e apenas uma fração corresponde a inscrições reais na Receita Federal. Para saber se um CPF está ativo, é preciso consultar uma base oficial ou um serviço autorizado.
Por que 111.111.111-11 passa no cálculo do módulo 11?
Porque a soma ponderada de dígitos iguais gera um resto que reproduz o próprio dígito. Todas as sequências repetidas de 000.000.000-00 a 999.999.999-99 satisfazem a fórmula, por isso praticamente todo validador de produção as rejeita explicitamente antes de calcular qualquer coisa.
O nono dígito do CPF indica a região de emissão?
Sim. O nono dígito é a região fiscal onde a inscrição foi feita — por exemplo, 8 corresponde a São Paulo e 7 ao Rio de Janeiro e Espírito Santo. Ele não influencia o cálculo dos verificadores e não deve ser usado como regra de negócio, já que a pessoa pode ter mudado de estado depois da emissão.
Devo validar CPF no frontend ou no backend?
Nos dois. No frontend a validação evita uma ida ao servidor e melhora a mensagem de erro; no backend ela é obrigatória, porque qualquer cliente pode ser contornado. Trate a validação do frontend como conveniência de interface e a do backend como regra.
Preciso guardar o CPF com ou sem pontuação?
Guarde apenas os onze dígitos e aplique a máscara na exibição. Isso evita duplicatas do mesmo documento gravadas em formatos diferentes, simplifica índices e comparações e deixa a formatação como responsabilidade exclusiva da camada de apresentação.

Ferramentas relacionadas

AL

Sobre o autor

Desenvolvedor de software no Brasil. Mantém o Codigio Labs desde a primeira ferramenta, escreve os artigos do site e revisa os textos quando a informação técnica muda.

Encontrou um erro ou tem uma correção a sugerir? Fale com o Codigio Labs. Correções relevantes são aplicadas com atualização da data de revisão do texto.

Continue lendo