Artigo Build·Desenvolvimento·13 min de leitura de leitura

Como Validar CPF e CNPJ (2026): Algoritmo, Código em JavaScript e Boas Práticas

Validar CPF e CNPJ é obrigatório em qualquer sistema brasileiro que lida com cadastro. Regex sozinho não basta — o algoritmo de módulo 11 descobre documentos falsos. Este guia mostra o cálculo completo, código pronto para frontend e backend, máscara em formulários e o que a LGPD exige.

Vitor Morais

Por Vitor Morais

Fundador do MochaLabz ·

Valide CPF/CNPJ na hora

Cole o número, confirme a validade pelo módulo 11 e veja a formatação correta.

Usar validador →

Validar CPF e CNPJ é um dos rituais de qualquer aplicação que lida com cadastro no Brasil. O algoritmo foi publicado pela Receita Federal em 1971 e segue o mesmo até hoje — módulo 11 aplicado aos dígitos do documento. Dominar esse cálculo garante que sua aplicação rejeite documentos inválidos sem chamar API externa e sem depender de biblioteca obscura.

Este guia cobre o algoritmo passo a passo, implementação em JavaScript e TypeScript (frontend e backend), validação com máscara em formulários, os erros mais comuns e o que a LGPD exige ao armazenar esses documentos.

Por que validação local compensa

Usar só regex deixa passar 99% dos CPFs inventados: qualquer sequência de 11 dígitos no formato bate com /^\\d{3}\\.?\\d{3}\\.?\\d{3}-?\\d{2}$/. O módulo 11 descarta 99% dessa sujeira sem um único request de rede. Benefícios:

  • Zero latência: validação instantânea, sem esperar API externa.
  • Zero custo: nada de pagar por consulta em serviço de terceiros.
  • Funciona offline: apps mobile e PWA validam mesmo sem internet.
  • Sem rate limit: você valida 10 mil documentos em ms.

A única coisa que validação local não faz: confirmar se o CPF existe de verdade na base da Receita. Para isso, precisa de API comercial (Serasa, SPC, Bureau) — que só vale em casos de alto risco (cadastro bancário, cobrança).

Anatomia do CPF

O CPF tem 11 dígitos divididos assim:

  • Posições 1–8: número sequencial.
  • Posição 9: região fiscal (1 a 9) — onde o CPF foi registrado.
  • Posições 10–11: dígitos verificadores calculados por módulo 11.
Regiões fiscais do 9º dígito do CPF
CritérioEstados
1DF, GO, MS, MT, TO
2AC, AM, AP, PA, RO, RR
3CE, MA, PI
4AL, PB, PE, RN
5BA, SE
6MG
7ES, RJ
8SP
9PR, SC
0RS

Algoritmo do CPF passo a passo

Exemplo: validar o CPF 123.456.789-09.

Passo 1: pegar os 9 primeiros dígitos

1 2 3 4 5 6 7 8 9

Passo 2: multiplicar por pesos decrescentes de 10 a 2

1 × 10 = 10 2 × 9 = 18 3 × 8 = 24 4 × 7 = 28 5 × 6 = 30 6 × 5 = 30 7 × 4 = 28 8 × 3 = 24 9 × 2 = 18 Soma = 210

Passo 3: calcular módulo 11

210 ÷ 11 = 19 com resto 1. O primeiro dígito verificador é 11 − 1 = 10 → quando o resultado é 10 ou 11, o dígito é 0. Logo: 0.

Passo 4: repetir com 10 dígitos e pesos de 11 a 2

1 × 11 = 11 2 × 10 = 20 3 × 9 = 27 4 × 8 = 32 5 × 7 = 35 6 × 6 = 36 7 × 5 = 35 8 × 4 = 32 9 × 3 = 27 0 × 2 = 0 Soma = 255 255 ÷ 11 = 23 resto 2 11 − 2 = 9 → segundo dígito = 9

Resultado esperado: 123.456.789-09. Confere com o CPF de entrada → CPF válido pelo módulo 11.

Implementação em JavaScript

function isCPFValid(cpf) { const digits = cpf.replace(/\D/g, ""); if (digits.length !== 11) return false; // Rejeita sequências repetidas (000..., 111..., etc.) if (/^(\d)\1{10}$/.test(digits)) return false; // Calcula dígito 1 let sum = 0; for (let i = 0; i < 9; i++) { sum += parseInt(digits[i]) * (10 - i); } let d1 = 11 - (sum % 11); if (d1 >= 10) d1 = 0; if (d1 !== parseInt(digits[9])) return false; // Calcula dígito 2 sum = 0; for (let i = 0; i < 10; i++) { sum += parseInt(digits[i]) * (11 - i); } let d2 = 11 - (sum % 11); if (d2 >= 10) d2 = 0; return d2 === parseInt(digits[10]); } isCPFValid("123.456.789-09"); // true isCPFValid("12345678909"); // true isCPFValid("000.000.000-00"); // false (repetição) isCPFValid("123.456.789-10"); // false (dígito errado)

Dica

O /^(\\d)\\1{10}$/ na linha 5 detecta sequências repetidas elegantemente. \\1 é backreference ao primeiro grupo capturado. Sem essa checagem, 999.999.999-99 passa no módulo 11 e gera bug sutil.

Anatomia do CNPJ

CNPJ tem 14 dígitos no formato XX.XXX.XXX/XXXX-XX:

  • Posições 1–8: número de registro da empresa.
  • Posições 9–12: número de filial (0001 = matriz).
  • Posições 13–14: dígitos verificadores.

Algoritmo do CNPJ

Segue a mesma lógica, mas com pesos diferentes por causa dos 13 dígitos iniciais.

function isCNPJValid(cnpj) { const digits = cnpj.replace(/\D/g, ""); if (digits.length !== 14) return false; if (/^(\d)\1{13}$/.test(digits)) return false; // Pesos para o primeiro dígito verificador const weights1 = [5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2]; let sum = 0; for (let i = 0; i < 12; i++) { sum += parseInt(digits[i]) * weights1[i]; } let d1 = 11 - (sum % 11); if (d1 >= 10) d1 = 0; if (d1 !== parseInt(digits[12])) return false; // Pesos para o segundo dígito verificador const weights2 = [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2]; sum = 0; for (let i = 0; i < 13; i++) { sum += parseInt(digits[i]) * weights2[i]; } let d2 = 11 - (sum % 11); if (d2 >= 10) d2 = 0; return d2 === parseInt(digits[13]); } isCNPJValid("00.000.000/0001-91"); // true isCNPJValid("11.222.333/0001-81"); // true isCNPJValid("00.000.000/0000-00"); // false (repetição)

Validação com TypeScript + validação única

Em TypeScript, tipar os inputs e reusar a lógica:

type DocumentType = "cpf" | "cnpj"; export function isValidDocument( doc: string, type?: DocumentType, ): boolean { const digits = doc.replace(/\D/g, ""); const docType = type ?? (digits.length === 11 ? "cpf" : "cnpj"); if (docType === "cpf") return isCPFValid(digits); if (docType === "cnpj") return isCNPJValid(digits); return false; } // Uso flexível isValidDocument("123.456.789-09"); // auto-detecta CPF isValidDocument("11.222.333/0001-81"); // auto-detecta CNPJ isValidDocument("12345678909", "cpf"); // força CPF

Máscara em formulários React

Máscara guia o usuário a preencher no formato correto (123.456.789-09) sem que ele precise digitar pontos e traços. Com react-imask:

import { IMaskInput } from "react-imask"; import { useState } from "react"; export function CPFInput() { const [value, setValue] = useState(""); const [error, setError] = useState<string | null>(null); const handleAccept = (val: string) => { setValue(val); if (val.replace(/\D/g, "").length === 11) { setError(isCPFValid(val) ? null : "CPF inválido"); } else { setError(null); } }; return ( <div> <IMaskInput mask="000.000.000-00" value={value} onAccept={handleAccept} placeholder="000.000.000-00" /> {error && <p className="text-red-600 text-sm">{error}</p>} </div> ); }

Validação no backend (Node.js)

O backend deve revalidar — sempre. Exemplo com Zod:

import { z } from "zod"; const schema = z.object({ nome: z.string().min(2), cpf: z .string() .transform((s) => s.replace(/\D/g, "")) .refine((s) => s.length === 11, { message: "CPF deve ter 11 dígitos" }) .refine(isCPFValid, { message: "CPF inválido" }), }); export async function POST(req: Request) { const body = await req.json(); const result = schema.safeParse(body); if (!result.success) { return Response.json( { errors: result.error.flatten() }, { status: 400 }, ); } // Salva com CPF já normalizado (só dígitos) await saveUser(result.data); return Response.json({ ok: true }); }

Bibliotecas populares em JavaScript

Bibliotecas de validação CPF/CNPJ
CritérioTamanhoExtras
cpf-cnpj-validator2 KBSimples, TypeScript nativo
brazilian-values10 KBValida CPF, CNPJ, CEP, telefone, etc.
@fnando/cpf + @fnando/cnpj1 KB cadaSeparado, tree-shakable
validator.js (pt-BR)17 KBSuporta isTaxID('pt-BR')

Contexto

Implementar o cálculo você mesmo (20 linhas de código) elimina uma dependência externa e deixa o código lido. Em projetos pequenos ou edge functions, vale mais que baixar biblioteca. Em projetos grandes, usar biblioteca bem testada economiza bug e manutenção.

Erros clássicos que geram bug em produção

  • Esquecer de descartar sequências repetidas: 000.000.000-00 e 111.111.111-11 passam no módulo 11. Todo validador sério descarta.
  • Não normalizar (trim, remover formatação): usuário pode colar CPF com espaços ou pontos extras.
  • Validar só no frontend: request direto via curl passa lixo pro banco.
  • Salvar com formatação no banco: guarde só os 11 dígitos. Formatação é camada de apresentação.
  • Logar CPF completo: viola LGPD. Mascare ou hash antes de logar.
  • Contar string em vez de dígitos: 123.456.789-09 tem 14 chars, 11 dígitos. Valide os 11, não os 14.

LGPD e armazenamento de CPF

CPF é dado pessoal sob LGPD. Requisitos mínimos:

  • Base legal: documentada no cadastro (ex.: “cumprimento de obrigação fiscal”, “execução de contrato”, “consentimento expresso”).
  • Criptografia em repouso: banco com CPFs criptografados no nível da coluna ou do disco.
  • Acesso restrito: não é todo sistema que precisa ver CPF. Aplique princípio do menor privilégio.
  • Logs mascarados: mostre só os últimos 2 ou 4 dígitos em logs e dashboards internos.
  • Retenção: exclua quando não for mais necessário. Contratos fiscais exigem 5 anos; cadastros de newsletter, provavelmente menos.
  • Direito à exclusão: mecanismo para o titular solicitar remoção.

Validar versus verificar existência real

Módulo 11 garante que o documento é matematicamente possível. Só API comercial confirma que o CPF existe na base da Receita.

Validação local vs API de consulta
CritérioValidação localAPI comercial
CustoZeroR$ 0,05 a R$ 5 por consulta
Latência< 1ms100–1500ms
DependênciasNenhumaInternet, contrato, rate limit
Verifica existênciaNãoSim
Retorna nomeNãoGeralmente sim (com autorização)
Quando usaSempreCadastros de alto risco, cobrança

Geração de CPF/CNPJ para testes

Em desenvolvimento e testes automatizados, use CPFs gerados — nunca reais. Algoritmo de geração é o inverso da validação: escolha 9 dígitos aleatórios (não todos iguais) e calcule os dois dígitos verificadores com módulo 11.

function generateCPF() { const digits = Array.from({ length: 9 }, () => Math.floor(Math.random() * 10), ); // Dígito 1 let sum = 0; for (let i = 0; i < 9; i++) sum += digits[i] * (10 - i); let d1 = 11 - (sum % 11); if (d1 >= 10) d1 = 0; digits.push(d1); // Dígito 2 sum = 0; for (let i = 0; i < 10; i++) sum += digits[i] * (11 - i); let d2 = 11 - (sum % 11); if (d2 >= 10) d2 = 0; digits.push(d2); return digits.join(""); }

Validação em uma frase

Validar CPF e CNPJ é barato, rápido e obrigatório. Módulo 11 cobre 99% dos erros de preenchimento com zero dependência externa. API comercial entra em cenário de risco (fraude, cobrança). Implemente local sempre, externo quando justificar.

Perguntas frequentes

Regex valida CPF corretamente?+

Só valida o formato — 11 dígitos com ou sem pontuação. O CPF também precisa ter dígitos verificadores matematicamente corretos via módulo 11. Regex aceita 000.000.000-00 (todos zeros passam no formato). Use regex como primeira barreira na UI e o algoritmo de módulo 11 como validação real, tanto no frontend quanto no backend.

Qual o algoritmo para validar CPF e CNPJ?+

Ambos usam módulo 11 com pesos diferentes. Para CPF: multiplicar cada um dos 9 primeiros dígitos por pesos de 10 a 2, somar, dividir por 11, subtrair o resto de 11. Se o resultado for 10 ou 11, o dígito é 0. Repetir para o segundo dígito com pesos de 11 a 2 sobre 10 dígitos. Para CNPJ, lógica idêntica mas com 12 dígitos base e pesos ligeiramente diferentes.

Por que CPFs com todos dígitos iguais passam no meu validador?+

Porque a matemática do módulo 11 aceita 000.000.000-00, 111.111.111-11 e todas as repetições como tecnicamente válidas. Mas a Receita Federal não emite CPFs nesse formato. Todo validador sério descarta explicitamente sequências de dígito único antes de aplicar o módulo 11. É um &ldquo;bug&rdquo; famoso em bibliotecas amadoras.

Devo validar no frontend ou no backend?+

Nos dois. Frontend dá feedback imediato e melhora a UX. Backend é a validação confiável — usuários podem desabilitar JavaScript ou enviar requests direto via curl. Nunca confie só em validação cliente para CPF/CNPJ; regras de negócio dependem da veracidade do documento. Validação dupla é barata e obrigatória em qualquer aplicação real.

Existe validador oficial da Receita Federal?+

Não para uso automatizado. A Receita oferece consulta pontual online (confirmação de CPF/CNPJ com nome e data de nascimento), mas tem CAPTCHA e rate limit — inadequado para validação em massa. Para verificar existência real de CPF, empresas usam APIs comerciais (Serasa, Bureau, SPC) pagas. Para validação apenas do algoritmo, o cálculo local é suficiente e gratuito.

Como lidar com CPF vs CPF Alfanumérico (novo formato)?+

A Receita anunciou CPFs alfanuméricos para documentos emitidos a estrangeiros e em casos específicos. Em 2026 ainda é minoritário, mas valide aceitando letras onde hoje é só dígito — ou rejeite explicitamente com mensagem clara se seu sistema não suporta. Cheque a documentação oficial da Receita antes de deploy em produção se CPF alfanumérico aparece como requisito.

Posso armazenar CPF no banco de dados?+

Sim, mas com responsabilidade LGPD. CPF é dado pessoal sensível. Requisitos mínimos: base legal documentada (consentimento, execução de contrato, obrigação legal), criptografia em repouso, acesso restrito com auditoria, retenção pelo tempo mínimo necessário, facilidade de exclusão sob solicitação. Nunca logue CPF completo — mascare (123.***.***-00) ou faça hash.

Como mostrar CPF mascarado na UI?+

Para UX de preenchimento, use máscara que formata enquanto o usuário digita (123.456.789-00). Bibliotecas populares: imask, react-imask, react-hook-form com pattern. Para exibição de CPF já salvo em admin, use máscara parcial (123.***.***-00) para proteger dados. Esse duplo uso da &ldquo;máscara&rdquo; é o padrão em sistemas SaaS brasileiros modernos.

#cpf#cnpj#validação#javascript#typescript#módulo 11#lgpd#react#formulário#brasil

Artigos relacionados