Node.js · algoritmo local + API

Validar CPF em Node.js

Para validar CPF em Node.js, 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 ES6 sem dependências, teste automatizado e conferência com CPFs gerados pela API.

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

TL;DR

const validaCpf = (cpf) => {
  const d = cpf.replace(/\D/g, '').split('').map(Number);
  if (d.length !== 11 || new Set(d).size === 1) return false;
  return [9, 10].every((i) => {
    const soma = d.slice(0, i).reduce((acc, n, k) => acc + n * (i + 1 - k), 0);
    return d[i] === ((soma * 10) % 11) % 10;
  });
};

console.log(validaCpf('529.982.247-25')); // true
console.log(validaCpf('529.982.247-26')); // false

Node 18+ (fetch nativo), sem npm install. Salve como .mjs e rode com node.

Rota 1: validar CPF em Node.js 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.mjs (ES modules, Node 18+, zero dependências)
import { fileURLToPath } from 'node:url';

const FORMATO_CPF = /^\d{3}\.?\d{3}\.?\d{3}-?\d{2}$/;

function digito(base) {
  // pesos decrescentes de base.length + 1 até 2
  const soma = base.reduce((acc, n, i) => acc + n * (base.length + 1 - i), 0);
  const resto = (soma * 10) % 11;
  return resto === 10 ? 0 : resto;
}

export function validaCpf(cpf) {
  if (typeof cpf !== 'string' || !FORMATO_CPF.test(cpf.trim())) return false;
  const d = cpf.replace(/\D/g, '').split('').map(Number);
  if (new Set(d).size === 1) return false; // 111.111.111-11 passa na conta, mas é inválido
  return d[9] === digito(d.slice(0, 9)) && d[10] === digito(d.slice(0, 10));
}

if (process.argv[1] === fileURLToPath(import.meta.url)) {
  for (const cpf of ['529.982.247-25', '52998224725', '529.982.247-26', '111.111.111-11', 'abc']) {
    console.log(cpf.padEnd(16), validaCpf(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.mjs (Node 18+). Salve o validador da Rota 1 como validador-cpf.mjs
import { validaCpf } from './validador-cpf.mjs';

const res = await fetch('https://fakeforge.com.br/api/generate?type=cpf&quantity=20');
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const { data: cpfs } = await res.json();

const trocaUltimoDigito = (cpf) => cpf.slice(0, -1) + ((Number(cpf.at(-1)) + 1) % 10);

const rejeitadosIndevidos = cpfs.filter((c) => !validaCpf(c));
const aceitosIndevidos = cpfs.filter((c) => validaCpf(trocaUltimoDigito(c)));

console.log(`${cpfs.length} CPFs da API | válidos rejeitados: ${rejeitadosIndevidos.length} | inválidos aceitos: ${aceitosIndevidos.length}`);
if (rejeitadosIndevidos.length || aceitosIndevidos.length) process.exit(1);

Como testar o validador de CPF com Jest

Com Jest em modo ESM. Os casos cobrem válidos, inválidos e as bordas de CPF.

// validador-cpf.test.mjs (Jest)
import { validaCpf } from './validador-cpf.mjs';

describe('validaCpf', () => {
  test.each(['529.982.247-25', '52998224725', '111.444.777-35'])('aceita %s', (cpf) => {
    expect(validaCpf(cpf)).toBe(true);
  });

  test.each([
    '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
    '',
  ])('rejeita %p', (cpf) => {
    expect(validaCpf(cpf)).toBe(false);
  });

  test('rejeita as 10 sequências repetidas', () => {
    for (let d = 0; d < 10; d++) expect(validaCpf(String(d).repeat(11))).toBe(false);
  });
});

// package.json: { "type": "module", "scripts": { "test": "NODE_OPTIONS=--experimental-vm-modules jest" } }

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 Node.js

Como validar CPF em Node.js?+

Use a função validaCpf 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. É ES6 puro, roda no Node 18+ e no navegador.

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