A função
JavaScript
function isValidCPF(cpf) {
cpf = String(cpf).replace(/\D/g, ''); // mantém só dígitos
if (cpf.length !== 11 || /^(\d)\1{10}$/.test(cpf)) return false; // 11 dígitos, não repetidos
const dv = (slice) => {
let sum = 0;
for (let i = 0; i < slice.length; i++) sum += +slice[i] * (slice.length + 1 - i);
const rest = (sum * 10) % 11;
return rest === 10 ? 0 : rest; // resto 10 vira 0
};
return dv(cpf.slice(0, 9)) === +cpf[9] // 1º dígito verificador
&& dv(cpf.slice(0, 10)) === +cpf[10]; // 2º dígito verificador
}
isValidCPF('111.444.777-35'); // true
isValidCPF('111.444.777-00'); // falseO cálculo é o do módulo 11: cada dígito é multiplicado por um peso decrescente, somado, e o resto da divisão por 11 define o verificador.
TypeScript
TypeScript
export function isValidCPF(value: string): boolean {
const cpf = value.replace(/\D/g, '');
if (cpf.length !== 11 || /^(\d)\1{10}$/.test(cpf)) return false;
const dv = (slice: string): number => {
let sum = 0;
for (let i = 0; i < slice.length; i++) sum += +slice[i] * (slice.length + 1 - i);
const rest = (sum * 10) % 11;
return rest === 10 ? 0 : rest;
};
return dv(cpf.slice(0, 9)) === +cpf[9] && dv(cpf.slice(0, 10)) === +cpf[10];
}publicidade
Com Zod (formulário)
TypeScript · Zod
import { z } from 'zod';
const schema = z.object({
cpf: z.string().refine(isValidCPF, { message: 'CPF inválido' }),
});O mesmo isValidCPF serve para React Hook Form (validate: isValidCPF), Yup e class-validator (em um decorator @IsCPF()).
Cuidados
- Regex só valida formato. Um padrão como
/^\d{11}$/confirma que são 11 dígitos, mas não confere o verificador — quem faz isso é a função acima. Veja regex de CPF e CNPJ. - Sequências repetidas (
11111111111) passariam no módulo 11, por isso a função as descarta antes. - Válido ≠ existe. A função confirma a consistência matemática, não se o CPF foi emitido a alguém.
- Guarde sem máscara (só os 11 dígitos) e formate só na exibição.
Continue
Código verificado por execução (casos válidos e inválidos). Algoritmo módulo 11 oficial. Revisado em 06/2026.