Validar, gerar e formatar CPF em Python
Funções em Python 3 sem dependências para validar, gerar e formatar CPF com o módulo 11, testes com pytest parametrize e uso da API com requests.
Para validar CPF em Python não é preciso instalar pacote nenhum: a biblioteca padrão tem tudo o que o algoritmo exige. O módulo abaixo funciona do Python 3.8 em diante e cobre os três pontos em que validadores costumam errar: sequências repetidas, a regra do resto menor que 2 e a pontuação da entrada. Se quiser entender cada etapa da conta antes do código, leia o guia do algoritmo do módulo 11.
Validar CPF em Python
import re
import secrets
_SEPARADORES = re.compile(r"[.\-\s]")
def _calcular_digito(digitos: str, peso_inicial: int) -> int:
soma = sum(int(d) * (peso_inicial - i) for i, d in enumerate(digitos))
resto = soma % 11
return 0 if resto < 2 else 11 - resto
def validar_cpf(valor: str) -> bool:
cpf = _SEPARADORES.sub("", valor or "")
if not re.fullmatch(r"[0-9]{11}", cpf):
return False
if cpf == cpf[0] * 11:
return False
dv1 = _calcular_digito(cpf[:9], 10)
dv2 = _calcular_digito(cpf[:10], 11)
return cpf[9:] == f"{dv1}{dv2}"Algumas escolhas são deliberadas:
[0-9]em vez de\d. Em Python,\dcasa qualquer dígito Unicode, inclusive os arábicos, eint()os converte sem reclamar. A classe explícita aceita só 0 a 9.re.fullmatchexige que a string inteira tenha 11 dígitos. Comre.match, um sufixo inesperado poderia passar.cpf == cpf[0] * 11recusa sequências repetidas. 111.111.111-11 passa no módulo 11, mas sequências assim não são consideradas válidas.valor or ""trataNonesem exceção.
Fazendo a conta com 529.982.247-25: a primeira soma é 295, o resto é 9 e o dígito é 2; a segunda soma é 347, o resto é 6 e o dígito é 5. A função compara "25" com "25" e devolve True. Com 529.982.247-26, compara "26" com "25" e devolve False.
Gerar CPF válido em Python
Use secrets em vez de random para não depender de uma semente previsível.
def gerar_cpf(formatado: bool = False) -> str:
while True:
base = "".join(str(secrets.randbelow(10)) for _ in range(9))
if base != base[0] * 9:
break
dv1 = _calcular_digito(base, 10)
dv2 = _calcular_digito(base + str(dv1), 11)
cpf = f"{base}{dv1}{dv2}"
return formatar_cpf(cpf) if formatado else cpfO laço descarta as dez bases repetidas, que gerariam CPFs como 111.111.111-11. O resultado é válido, mas pode coincidir com um CPF real por acaso; use-o em fixtures e bancos de teste, nunca como dado de uma pessoa. O guia de massa de teste e LGPD detalha esse cuidado.
Se o teste depende do estado de emissão, fixe o nono dígito em vez de sorteá-lo: ele indica a região fiscal, e 8 corresponde a São Paulo. Basta gerar oito dígitos aleatórios, acrescentar o dígito da região e seguir com o mesmo cálculo dos verificadores; 529.982.248-06 é um exemplo válido de SP. A tabela completa está no guia sobre os dígitos do CPF e as regiões fiscais. Para gerar centenas de números de uma vez sem escrever código, use o gerador de CPF em lote.
Formatar e limpar CPF em Python
def limpar_cpf(valor: str) -> str:
return re.sub(r"[^0-9]", "", valor or "")
def formatar_cpf(valor: str) -> str:
d = limpar_cpf(valor)
if len(d) != 11:
raise ValueError(f"CPF precisa de 11 dígitos, recebeu {len(d)}")
return f"{d[:3]}.{d[3:6]}.{d[6:9]}-{d[9:]}"formatar_cpf("52998224725") devolve "529.982.247-25", e limpar_cpf("529.982.247-25") devolve "52998224725". A formatação recusa tamanhos diferentes de 11 com ValueError em vez de completar com zeros: se um CPF vindo de uma coluna numérica perdeu o zero à esquerda, corrija com str(numero).zfill(11) na migração, onde você sabe a origem do dado. O guia sobre validar CPF no banco de dados trata desse caso.
Testes
Com pytest, parametrize transforma cada tupla em um teste separado, e a saída mostra qual caso falhou.
import pytest
from cpf import formatar_cpf, gerar_cpf, limpar_cpf, validar_cpf
@pytest.mark.parametrize(
("cpf", "esperado"),
[
("529.982.247-25", True),
("111.111.111-11", False),
("529.982.247-26", False),
],
)
def test_validar_cpf(cpf, esperado):
assert validar_cpf(cpf) is esperado
def test_gerados_sao_validos():
assert all(validar_cpf(gerar_cpf()) for _ in range(1000))
def test_formatar_e_limpar():
assert formatar_cpf("52998224725") == "529.982.247-25"
assert limpar_cpf("529.982.247-25") == "52998224725"Rode com pytest -v. Para mais casos de borda, como entrada com letras ou com 10 dígitos, veja os erros comuns ao validar CPF.
Usar a API em vez de reimplementar
A API do cpf.dev.br valida e gera CPFs por HTTP, sem chave, com limite de 60 requisições por minuto por IP. Com requests:
import requests
r = requests.get("https://www.cpf.dev.br/api/v1/cpf/validar/529.982.247-25", timeout=5)
r.raise_for_status()
print(r.json())
# {'valido': True, 'cpf': '52998224725', 'formatado': '529.982.247-25', 'uf': ['ES', 'RJ']}
lote = requests.get(
"https://www.cpf.dev.br/api/v1/cpf/gerar",
params={"quantidade": 5, "uf": "SP", "formatado": "true"},
timeout=5,
)
print(lote.json()["cpfs"])Sem requests, urllib.request.urlopen e json.load fazem o mesmo. Para validar formulários em Django ou FastAPI, prefira a função local, que não depende de rede. Para conferir um número rapidamente, use o validador de CPF.