Python · algoritmo local + API

Validar CPF em Python

Para validar CPF em Python, exija 11 dígitos e recalcule os dois dígitos verificadores pelo mod-11 da Receita Federal, com pesos 10 a 2 e 11 a 2. CPFs com todos os dígitos iguais são rejeitados mesmo quando a conta bate. A validação confirma só a matemática, não se o CPF está ativo. Abaixo: uma função Python só com a biblioteca padrão, teste automatizado e conferência com CPFs gerados pela API.

Fonte: algoritmo de dígito verificador do CPF, definido pela Receita Federal.

TL;DR

def valida_cpf(cpf: str) -> bool:
    d = [int(c) for c in cpf if c.isdigit()]
    if len(d) != 11 or len(set(d)) == 1:
        return False
    for i in (9, 10):
        soma = sum(n * p for n, p in zip(d[:i], range(i + 1, 1, -1)))
        if d[i] != (soma * 10 % 11) % 10:
            return False
    return True


print(valida_cpf("529.982.247-25"))  # True
print(valida_cpf("529.982.247-26"))  # False

Python 3.9+, sem pip install. Salve cada bloco no arquivo indicado no topo.

Rota 1: validar CPF em Python com o algoritmo local

Versão completa, pronta pra colar no projeto. Aceita CPF com ou sem pontuação, rejeita caracteres estranhos e as 10 sequências repetidas.

# validador_cpf.py (só stdlib)
import re

FORMATO_CPF = re.compile(r"\d{3}\.?\d{3}\.?\d{3}-?\d{2}")


def _digito(base: list[int]) -> int:
    """Um DV: pesos decrescentes de len(base)+1 até 2, resto de (soma * 10) % 11."""
    soma = sum(n * p for n, p in zip(base, range(len(base) + 1, 1, -1)))
    resto = (soma * 10) % 11
    return 0 if resto == 10 else resto


def valida_cpf(cpf: str) -> bool:
    """Valida CPF pelo mod-11 da Receita Federal, com ou sem pontuação."""
    if not FORMATO_CPF.fullmatch(cpf.strip()):
        return False
    d = [int(c) for c in cpf if c.isdigit()]
    if len(set(d)) == 1:  # 111.111.111-11 passa na conta, mas é inválido
        return False
    return d[9] == _digito(d[:9]) and d[10] == _digito(d[:10])


if __name__ == "__main__":
    for cpf in ("529.982.247-25", "52998224725", "529.982.247-26", "111.111.111-11", "abc"):
        print(f"{cpf!r:20} -> {valida_cpf(cpf)}")

Como o cálculo do dígito verificador do CPF funciona

Um exemplo calculado à mão, para você conferir o código contra a conta.

CPF 529.982.247-25

1º DV: 5×10 + 2×9 + 9×8 + 9×7 + 8×6 + 2×5 + 2×4 + 4×3 + 7×2
      = 295
      (295 × 10) mod 11 = 2  ->  DV1 = 2  (resto 10 viraria 0)

2º DV: 5×11 + 2×10 + 9×9 + 9×8 + 8×7 + 2×6 + 2×5 + 4×4 + 7×3 + 2×2
      = 347
      (347 × 10) mod 11 = 5  ->  DV2 = 5

Resultado: 529.982.247-25

Rota 2: conferir o validador com CPFs da API do FakeForge

A API do FakeForge gera CPFs válidos, mas não tem endpoint de validação. O uso útil é como oráculo de teste: todo CPF gerado precisa passar no seu validador, e o mesmo CPF com o último dígito trocado precisa falhar.

# confere_cpf_api.py (stdlib). Salve o validador da Rota 1 como validador_cpf.py
import json
import urllib.request

from validador_cpf import valida_cpf

URL = "https://fakeforge.com.br/api/generate?type=cpf&quantity=20"

with urllib.request.urlopen(URL, timeout=10) as resp:
    cpfs = json.load(resp)["data"]


def troca_ultimo_digito(cpf: str) -> str:
    return cpf[:-1] + str((int(cpf[-1]) + 1) % 10)


rejeitados_indevidos = [c for c in cpfs if not valida_cpf(c)]
aceitos_indevidos = [c for c in cpfs if valida_cpf(troca_ultimo_digito(c))]

print(f"{len(cpfs)} CPFs da API | válidos rejeitados: {len(rejeitados_indevidos)} | inválidos aceitos: {len(aceitos_indevidos)}")
assert not rejeitados_indevidos and not aceitos_indevidos

Como testar o validador de CPF com pytest

Rode com pytest -q. Os casos cobrem válidos, inválidos e as bordas de CPF.

# test_validador_cpf.py (pytest)
import pytest

from validador_cpf import valida_cpf

VALIDOS = ["529.982.247-25", "52998224725", "111.444.777-35"]
INVALIDOS = [
    "529.982.247-26",  # DV errado
    "111.111.111-11",  # dígitos repetidos
    "529.982.247-2",   # curto demais
    "529.982.247-2a",  # caractere inválido
    "",
]


@pytest.mark.parametrize("cpf", VALIDOS)
def test_aceita_cpf_valido(cpf):
    assert valida_cpf(cpf) is True


@pytest.mark.parametrize("cpf", INVALIDOS)
def test_rejeita_cpf_invalido(cpf):
    assert valida_cpf(cpf) is False


def test_todas_as_repeticoes_sao_rejeitadas():
    assert not any(valida_cpf(str(d) * 11) for d in range(10))

Validar CPF: algoritmo local ou serviço externo

CenárioAlgoritmo localAPI FakeForge (geração)
Confere os dígitos verificadoresSimNão, a API só gera
Gera CPFs válidos para testeNãoSim, até 10.000 por chamada
Funciona offlineSimNão
Confirma que o CPF está ativo na ReceitaNãoNão
DependênciasNenhumaUma chamada HTTP
CustoR$ 0Grátis até 50 chamadas por dia

Perguntas frequentes sobre validar CPF em Python

Como validar CPF em Python?+

Use a função valida_cpf desta página: ela aceita CPF com ou sem pontuação, rejeita sequências repetidas como 111.111.111-11 e confere os dois dígitos verificadores pelo mod-11. Só biblioteca padrão, sem pip install.

Como funciona o cálculo dos dígitos verificadores do CPF?+

Os 9 primeiros dígitos são multiplicados por pesos de 10 a 2, somados, o total é multiplicado por 10 e se toma o resto da divisão por 11. Resto 10 vira 0. O segundo dígito repete a conta com 10 dígitos e pesos de 11 a 2.

CPF válido quer dizer que o CPF existe?+

Não. A validação confere só a matemática dos dígitos verificadores. Saber se o CPF está regular exige consulta à Receita Federal, que não cabe num validador de formulário.

Por que 111.111.111-11 é inválido se a conta bate?+

Sequências de um dígito repetido passam no cálculo mod-11, mas a Receita Federal não emite esses números. Todo validador deve rejeitar os 10 casos, de 000.000.000-00 a 999.999.999-99.

A API do FakeForge valida CPF?+

Não. A API gera CPFs válidos com GET /api/generate?type=cpf, e a validação roda no seu código. Use os CPFs gerados como casos positivos e troque o último dígito para obter casos negativos.

Páginas relacionadas