Entendendo a Validação de CPF
Se você já desenvolveu um sistema de cadastro no Brasil, provavelmente precisou validar CPFs. Mas você sabe como funciona a matemática por trás dessa validação? Neste artigo, vamos destrinchar o algoritmo e implementá-lo do zero em três linguagens diferentes.
📋 O que é o CPF?
O CPF (Cadastro de Pessoas Físicas) é um documento de identificação fiscal emitido pela Receita Federal do Brasil. Possui 11 dígitos no formato:
XXX.XXX.XXX-DDOs dois últimos dígitos (DD) são os dígitos verificadores
Os 9 primeiros dígitos identificam a pessoa e são atribuídos pela Receita Federal. Os 2 últimos dígitos são calculados a partir dos 9 primeiros usando o algoritmo de módulo 11.
🔢 O Algoritmo Módulo 11
O módulo 11 é um algoritmo de checksum usado em diversos documentos brasileiros (CPF, CNPJ, títulos de eleitor). Funciona assim:
Passo 1: Calcular o primeiro dígito verificador
Vamos usar o CPF 123.456.789-?? como exemplo:
- Multiplique cada um dos 9 primeiros dígitos por pesos decrescentes de 10 a 2
- Some todos os resultados
- Calcule o resto da divisão por 11
- Se o resto for menor que 2, o dígito é 0; caso contrário, é 11 menos o resto
Dígitos: 1 2 3 4 5 6 7 8 9
Pesos: 10 9 8 7 6 5 4 3 2
─────────────────────────────────────
Produtos: 10 18 24 28 30 30 28 24 18
Soma = 10 + 18 + 24 + 28 + 30 + 30 + 28 + 24 + 18 = 210
Resto = 210 % 11 = 1
Primeiro dígito = 11 - 1 = 0 (ou zero se resto < 2)Passo 2: Calcular o segundo dígito verificador
Agora incluímos o primeiro dígito verificador (0) e usamos pesos de 11 a 2:
Dígitos: 1 2 3 4 5 6 7 8 9 0
Pesos: 11 10 9 8 7 6 5 4 3 2
─────────────────────────────────────────
Produtos: 11 20 27 32 35 36 35 32 27 0
Soma = 255
Resto = 255 % 11 = 2
Segundo dígito = 11 - 2 = 9Resultado: o CPF válido seria 123.456.789-09
⚠️ CPFs Inválidos por Padrão
CPFs com todos os dígitos iguais (111.111.111-11, 222.222.222-22, etc.) passam na validação matemática, mas são considerados inválidos e devem ser rejeitados.
💻 Implementação em JavaScript
function validarCPF(cpf) {
// Remove caracteres não numéricos
cpf = cpf.replace(/\D/g, '');
// Verifica se tem 11 dígitos
if (cpf.length !== 11) return false;
// Rejeita CPFs com todos os dígitos iguais
if (/^(\d)\1{10}$/.test(cpf)) return false;
// Calcula o primeiro dígito verificador
let soma = 0;
for (let i = 0; i < 9; i++) {
soma += parseInt(cpf.charAt(i)) * (10 - i);
}
let resto = soma % 11;
let digito1 = resto < 2 ? 0 : 11 - resto;
// Verifica o primeiro dígito
if (digito1 !== parseInt(cpf.charAt(9))) return false;
// Calcula o segundo dígito verificador
soma = 0;
for (let i = 0; i < 10; i++) {
soma += parseInt(cpf.charAt(i)) * (11 - i);
}
resto = soma % 11;
let digito2 = resto < 2 ? 0 : 11 - resto;
// Verifica o segundo dígito
return digito2 === parseInt(cpf.charAt(10));
}
// Exemplos de uso:
console.log(validarCPF("123.456.789-09")); // true
console.log(validarCPF("111.111.111-11")); // false🐍 Implementação em Python
import re
def validar_cpf(cpf: str) -> bool:
# Remove caracteres não numéricos
cpf = re.sub(r'\D', '', cpf)
# Verifica se tem 11 dígitos
if len(cpf) != 11:
return False
# Rejeita CPFs com todos os dígitos iguais
if cpf == cpf[0] * 11:
return False
# Calcula o primeiro dígito verificador
soma = sum(int(cpf[i]) * (10 - i) for i in range(9))
resto = soma % 11
digito1 = 0 if resto < 2 else 11 - resto
if digito1 != int(cpf[9]):
return False
# Calcula o segundo dígito verificador
soma = sum(int(cpf[i]) * (11 - i) for i in range(10))
resto = soma % 11
digito2 = 0 if resto < 2 else 11 - resto
return digito2 == int(cpf[10])
# Exemplos de uso:
print(validar_cpf("123.456.789-09")) # True
print(validar_cpf("111.111.111-11")) # False☕ Implementação em Java
public class ValidadorCPF {
public static boolean validar(String cpf) {
// Remove caracteres não numéricos
cpf = cpf.replaceAll("\\D", "");
// Verifica se tem 11 dígitos
if (cpf.length() != 11) return false;
// Rejeita CPFs com todos os dígitos iguais
if (cpf.matches("(\\d)\\1{10}")) return false;
// Calcula o primeiro dígito verificador
int soma = 0;
for (int i = 0; i < 9; i++) {
soma += Character.getNumericValue(cpf.charAt(i)) * (10 - i);
}
int resto = soma % 11;
int digito1 = resto < 2 ? 0 : 11 - resto;
if (digito1 != Character.getNumericValue(cpf.charAt(9))) {
return false;
}
// Calcula o segundo dígito verificador
soma = 0;
for (int i = 0; i < 10; i++) {
soma += Character.getNumericValue(cpf.charAt(i)) * (11 - i);
}
resto = soma % 11;
int digito2 = resto < 2 ? 0 : 11 - resto;
return digito2 == Character.getNumericValue(cpf.charAt(10));
}
public static void main(String[] args) {
System.out.println(validar("123.456.789-09")); // true
System.out.println(validar("111.111.111-11")); // false
}
}⚠️ Erros Comuns
- Não remover caracteres especiais: Sempre limpe o CPF antes de validar (pontos e hífen)
- Aceitar CPFs com dígitos repetidos: 000.000.000-00 até 999.999.999-99 passam na validação matemática mas são inválidos
- Confundir validação com verificação: Um CPF pode ser matematicamente válido mas não existir na Receita Federal
- Usar apenas regex: Regex valida apenas o formato, não os dígitos verificadores
🎯 Conclusão
Agora você entende como funciona a validação de CPF por dentro! O algoritmo de módulo 11 é elegante e eficiente, permitindo detectar erros de digitação com alta precisão. As implementações apresentadas podem ser facilmente adaptadas para validar CNPJ (que usa o mesmo princípio, com pesos diferentes).
🛠️ Precisa validar um CPF rapidamente?
Usar Validador de CPF/CNPJ →