Como Gerar CPF Válido em JavaScript: Algoritmo Completo
Gerar um CPF matematicamente válido em JavaScript é trivial depois que você entende o algoritmo de módulo 11. Este guia traz o código completo (20 linhas), variações (TypeScript, geração em lote, por região fiscal, com máscara) e o contexto legal — porque CPF gerado pode coincidir com um real.
Por Vitor Morais
Fundador do MochaLabz ·
Prefere uma ferramenta pronta?
Gere CPFs válidos para teste com formatação, em lote e opção por estado — 100% no navegador.
Usar gerador de CPF →Gerar um CPF matematicamente válido em JavaScript é trivial depois de entender o algoritmo de módulo 11 que a Receita Federal usa para calcular os dígitos verificadores. Em ~20 linhas você tem uma função pronta; em 50 linhas tem uma versão robusta com TypeScript, geração em lote e por região fiscal. Este guia cobre tudo, com o contexto legal importante (CPFs gerados podem coincidir com CPFs reais — use apenas em testes).
Como o algoritmo do CPF funciona
O CPF tem 11 dígitos. Os 9 primeiros são o número-base (sequencial emitido pela Receita); os 2 últimos são os dígitos verificadores (DV) calculados com módulo 11 sobre os 9 primeiros. Para gerar um CPF válido, basta:
- Gerar 9 dígitos aleatórios (o número-base).
- Calcular o 1º DV com módulo 11 (pesos 10 a 2).
- Calcular o 2º DV com módulo 11 (pesos 11 a 2).
- Rejeitar sequências repetidas (111...1, 222...2 etc).
Para a teoria detalhada do módulo 11, veja algoritmo do dígito verificador do CPF.
Implementação completa em JavaScript
/**
* Calcula um dígito verificador via módulo 11.
* @param digits - array de dígitos base
* @param pesoInicial - peso do primeiro dígito (10 para DV1, 11 para DV2)
*/
function calcDV(digits, pesoInicial) {
const soma = digits.reduce(
(acc, d, i) => acc + d * (pesoInicial - i),
0,
);
const resto = soma % 11;
return resto < 2 ? 0 : 11 - resto;
}
/**
* Gera um CPF matematicamente válido.
* @param format - true retorna "000.000.000-00"; false retorna "00000000000"
*/
function generateCPF(format = true) {
// 1. Gera 9 dígitos aleatórios
const base = Array.from(
{ length: 9 },
() => Math.floor(Math.random() * 10),
);
// 2. Rejeita sequências repetidas (000...0 até 999...9)
if (base.every((d) => d === base[0])) return generateCPF(format);
// 3. Calcula os dois dígitos verificadores
const dv1 = calcDV(base, 10);
const dv2 = calcDV([...base, dv1], 11);
const cpf = [...base, dv1, dv2].join('');
if (!format) return cpf;
// 4. Aplica máscara XXX.XXX.XXX-XX
return cpf.replace(/(\d{3})(\d{3})(\d{3})(\d{2})/, '$1.$2.$3-$4');
}
// Uso
generateCPF(); // "432.519.873-05"
generateCPF(false); // "43251987305"Versão em TypeScript
function calcDV(digits: number[], pesoInicial: number): number {
const soma = digits.reduce(
(acc, d, i) => acc + d * (pesoInicial - i),
0,
);
const resto = soma % 11;
return resto < 2 ? 0 : 11 - resto;
}
export function generateCPF(format = true): string {
const base = Array.from(
{ length: 9 },
() => Math.floor(Math.random() * 10),
);
if (base.every((d) => d === base[0])) return generateCPF(format);
const dv1 = calcDV(base, 10);
const dv2 = calcDV([...base, dv1], 11);
const cpf = [...base, dv1, dv2].join('');
if (!format) return cpf;
return cpf.replace(/(\d{3})(\d{3})(\d{3})(\d{2})/, '$1.$2.$3-$4');
}
export function generateCPFs(count: number, format = true): string[] {
return Array.from({ length: count }, () => generateCPF(format));
}Geração em lote com unicidade garantida
Para muitos CPFs sem duplicatas, use Set para deduplicar:
function generateUniqueCPFs(count: number, format = true): string[] {
const set = new Set<string>();
while (set.size < count) {
set.add(generateCPF(false)); // sempre sem máscara no Set
}
const arr = Array.from(set);
if (!format) return arr;
return arr.map((cpf) =>
cpf.replace(/(\d{3})(\d{3})(\d{3})(\d{2})/, '$1.$2.$3-$4')
);
}
// 10 mil CPFs únicos em ~50ms no Node moderno
const cpfs = generateUniqueCPFs(10_000);Lotes muito grandes
Para lotes > 100k, gere sequencialmente partindo de um número-base incrementando em 1 e calculando os DVs. Garante unicidade sem custo de hash do Set, útil em seeds massivos de banco de dados.
Gerar CPF de uma região fiscal específica
O 9º dígito do CPF (posição 9 do número-base de 11 dígitos) identifica a região fiscal. Para gerar CPF de SP, por exemplo, fixe o 9º dígito como 8:
| Critério | Região Fiscal |
|---|---|
| 1 | DF, GO, MS, MT, TO |
| 2 | AC, AM, AP, PA, RO, RR |
| 3 | CE, MA, PI |
| 4 | AL, PB, PE, RN |
| 5 | BA, SE |
| 6 | MG |
| 7 | ES, RJ |
| 8 | SP |
| 9 | PR, SC |
| 0 | RS |
type RegiaoFiscal = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
export function generateCPFByRegion(
regiao: RegiaoFiscal,
format = true,
): string {
// 8 dígitos aleatórios + regiao na posição 9
const base = [
...Array.from({ length: 8 }, () => Math.floor(Math.random() * 10)),
regiao,
];
// Evita sequência toda igual (caso particular quando regiao
// também é o dígito aleatório)
if (base.every((d) => d === base[0])) return generateCPFByRegion(regiao, format);
const dv1 = calcDV(base, 10);
const dv2 = calcDV([...base, dv1], 11);
const cpf = [...base, dv1, dv2].join('');
if (!format) return cpf;
return cpf.replace(/(\d{3})(\d{3})(\d{3})(\d{2})/, '$1.$2.$3-$4');
}
generateCPFByRegion(8); // CPF emitido em SP
generateCPFByRegion(6); // CPF emitido em MGVersão com crypto.getRandomValues
Para apps que precisam de aleatoriedade criptograficamente forte (raro em geração de CPF de teste, mas disponível):
function randomDigit(): number {
// Usa 4 bytes e mapeia para 0-9 sem módulo bias
const buf = new Uint32Array(1);
crypto.getRandomValues(buf);
return buf[0] % 10;
}
export function generateCPFCrypto(format = true): string {
const base = Array.from({ length: 9 }, randomDigit);
if (base.every((d) => d === base[0])) return generateCPFCrypto(format);
const dv1 = calcDV(base, 10);
const dv2 = calcDV([...base, dv1], 11);
const cpf = [...base, dv1, dv2].join('');
if (!format) return cpf;
return cpf.replace(/(\d{3})(\d{3})(\d{3})(\d{2})/, '$1.$2.$3-$4');
}Integrando com Faker.js
Para gerar personas fictícias completas (nome, e-mail, endereço e CPF), combine com Faker.js:
// npm install @faker-js/faker
import { fakerPT_BR as faker } from '@faker-js/faker';
export interface Persona {
nome: string;
cpf: string;
email: string;
telefone: string;
endereco: {
rua: string;
cidade: string;
uf: string;
cep: string;
};
}
export function generatePersona(): Persona {
return {
nome: faker.person.fullName(),
cpf: generateCPF(),
email: faker.internet.email(),
telefone: faker.phone.number({ style: 'national' }),
endereco: {
rua: faker.location.street(),
cidade: faker.location.city(),
uf: faker.location.state({ abbreviated: true }),
cep: faker.location.zipCode('#####-###'),
},
};
}
// Gerar 100 personas para seed de teste
const users = Array.from({ length: 100 }, generatePersona);Testes para o gerador
// __tests__/cpf.test.ts (Vitest / Jest)
import { describe, expect, it } from 'vitest';
import { generateCPF, generateCPFs, validateCPF } from './cpf';
describe('generateCPF', () => {
it('gera CPF no formato XXX.XXX.XXX-XX', () => {
expect(generateCPF()).toMatch(/^\d{3}\.\d{3}\.\d{3}-\d{2}$/);
});
it('gera CPF sem máscara quando format=false', () => {
expect(generateCPF(false)).toMatch(/^\d{11}$/);
});
it('gera CPF que passa na validação', () => {
for (let i = 0; i < 100; i++) {
expect(validateCPF(generateCPF())).toBe(true);
}
});
it('nunca gera sequência repetida', () => {
for (let i = 0; i < 10_000; i++) {
const cpf = generateCPF(false);
expect(cpf).not.toMatch(/^(\d)\1{10}$/);
}
});
});
describe('generateCPFs', () => {
it('gera a quantidade pedida', () => {
expect(generateCPFs(50)).toHaveLength(50);
});
});Validação (complementar à geração)
A mesma função calcDV serve para validar um CPF fornecido:
export function validateCPF(input: string): boolean {
const cpf = input.replace(/[^\d]/g, '');
if (cpf.length !== 11) return false;
if (/^(\d)\1{10}$/.test(cpf)) return false;
const nums = cpf.split('').map(Number);
const dv1 = calcDV(nums.slice(0, 9), 10);
const dv2 = calcDV(nums.slice(0, 10), 11);
return nums[9] === dv1 && nums[10] === dv2;
}
validateCPF('432.519.873-05'); // true (ou false, depende do cálculo)
validateCPF('111.111.111-11'); // false (repetido)
validateCPF('abc'); // false (formato errado)CPF alfanumérico (a partir de julho/2026)
A partir de julho de 2026, a Receita começa a emitir CPFs com letras (A-Z) nos 9 primeiros caracteres. Os 2 últimos continuam sendo dígitos verificadores. Versão adaptada do gerador:
// Alfabeto permitido nas 9 primeiras posições
const ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
function toValue(c: string): number {
// Valor ASCII menos 48 (padrão Receita)
return c.charCodeAt(0) - 48;
}
export function generateCPFAlfa(format = true): string {
const base = Array.from(
{ length: 9 },
() => ALPHABET[Math.floor(Math.random() * ALPHABET.length)],
);
// DV usa valor ASCII-48 de cada caractere
const values = base.map(toValue);
const calcDVAlfa = (vals: number[], pesoInicial: number) => {
const soma = vals.reduce(
(acc, v, i) => acc + v * (pesoInicial - i),
0,
);
const resto = soma % 11;
return resto < 2 ? 0 : 11 - resto;
};
const dv1 = calcDVAlfa(values, 10);
const dv2 = calcDVAlfa([...values, dv1], 11);
const cpf = [...base, String(dv1), String(dv2)].join('');
if (!format) return cpf;
return cpf.replace(/^(.{3})(.{3})(.{3})(.{2})$/, '$1.$2.$3-$4');
}
// Exemplo: "AB2.5C7.89X-42"Comparativo de implementações
| Critério | Quando usar |
|---|---|
| Implementação manual (mostrada acima) | Aprendizado, controle total, sem dependência |
| @faker-js/faker (faker.br.cpf) | Personas completas em massa, seed de banco |
| cpf-cnpj-validator (npm) | Só validação — não gera |
| brazilian-values (npm) | Validar + gerar + formatar, TypeScript-first |
| Gerador online (sem código) | Testes manuais, populando forms UI |
Aviso legal importante
Use apenas em testes
CPFs gerados por algoritmo são matematicamente válidos, mas podem coincidir com CPFs de pessoas reais. Há 1 bilhão de combinações possíveis de número-base, e a Receita já emitiu mais de 280 milhões de CPFs — a probabilidade de colisão é baixa mas não zero.
Usar CPF gerado para qualquer transação real (abrir conta, cadastro fiscal, compra em nome de terceiro) pode configurar falsidade ideológica e estelionato — crimes previstos nos artigos 299 e 171 do Código Penal. Use SEMPRE apenas em ambientes de desenvolvimento e teste isolados.
Casos de uso legítimos
- Seed de banco de dados para desenvolvimento local.
- Dados fictícios para QA em ambientes de staging/teste.
- Testes automatizados (unit, integração, e2e) que precisam de CPF válido.
- Validação de formulários com payload sintético.
- Demos e screencasts sem expor dados reais.
- Load testing com usuários sintéticos.
- Mock de API em desenvolvimento offline.
Para contexto completo sobre testes com dados fictícios, veja CPF para testes: como usar com segurança e dados fictícios para testes de software.
Erros comuns ao implementar
Armadilhas frequentes
- Esquecer de rejeitar sequências repetidas: 111.111.111-11 passa no módulo 11 mas é oficialmente inválido.
- Usar Math.floor(Math.random() * 10) em loop sem Array.from: JS tem semântica peculiar em
new Array(n).fill()— prefiraArray.from. - Peso errado no DV2: começa em 11, não em 10. Erro comum que gera CPFs com DV2 inválido.
- Não validar o resultado: sempre teste o CPF gerado contra sua função de validação para pegar bugs.
- Formatar antes de usar em teste: armazene os 11 dígitos puros; formate só na exibição.
- Regex de máscara mal feita:
(\d{3})(\d{3})(\d{3})(\d{2})exige exatamente 11 dígitos; verifique antes de aplicar.
Checklist do gerador completo
- ✅ Função
calcDVisolada, testável e reutilizável. - ✅ Geração de 9 dígitos aleatórios com
Math.random()oucrypto.getRandomValues(). - ✅ Rejeição de sequências repetidas.
- ✅ Cálculo dos 2 DVs com pesos corretos (10-2 e 11-2).
- ✅ Opção de formatar com máscara ou não.
- ✅ Versão em lote deduplicada (Set ou sequencial).
- ✅ Variante por região fiscal quando útil.
- ✅ Testes cobrindo valid, mask, sem mask, lote, sequências repetidas.
- ✅ Integração com Faker.js para personas completas.
- ✅ Comentários / documentação sobre uso apenas em teste.
- ✅ Uma linha explícita de aviso legal no README.
Perguntas frequentes
É legal gerar CPFs válidos em código?+
Gerar CPFs matematicamente válidos para uso em DESENVOLVIMENTO e TESTES é completamente legal. O que é crime é usar CPF alheio (real, de outra pessoa) sem autorização ou para se passar por alguém (falsidade ideológica, estelionato). CPFs gerados por algoritmo passam na validação matemática mas NÃO são cadastrados na Receita Federal — são apenas 11 dígitos que seguem a regra do módulo 11.
Um CPF gerado pode coincidir com o de uma pessoa real?+
Matematicamente, pode — há apenas 9 dígitos-base possíveis (1 bilhão de combinações), e a Receita já emitiu mais de 280 milhões de CPFs. Por isso NUNCA use CPFs gerados fora de ambiente de teste: é possível que um CPF fictício "bata" com o de alguém real, e usar isso para transações reais é crime independente da intenção.
Math.random() é seguro para gerar CPF?+
Para testes e desenvolvimento, é perfeitamente adequado. Math.random() não é criptograficamente seguro (previsível com esforço), mas para seedar dados fictícios que não precisam ser imprevisíveis, funciona bem. Para aplicações onde imprevisibilidade importa (geração de tokens, IDs de sessão), use crypto.getRandomValues() — mas CPF de teste não é um desses casos.
Como gerar CPF de um estado específico?+
O 9º dígito do CPF (posição 9 do número-base) identifica a região fiscal: 1=DF/GO/MS/MT/TO, 2=AC/AM/AP/PA/RO/RR, 3=CE/MA/PI, 4=AL/PB/PE/RN, 5=BA/SE, 6=MG, 7=ES/RJ, 8=SP, 9=PR/SC, 0=RS. Para gerar CPF de SP, basta fixar o 9º dígito como 8 antes de calcular os verificadores.
Como integrar com Faker.js para dados fictícios completos?+
Faker.js tem locale pt-BR com faker.br.cpf(), mas a implementação do Faker só funciona em @faker-js/faker 8+. Para personas completas (nome + email + CPF + endereço), combine faker.person.fullName() + faker.internet.email() + sua função generateCPF(). Bibliotecas como brazilian-values do GitHub também oferecem geradores específicos com boa qualidade.
Posso gerar CPF alfanumérico para testes do novo formato 2026?+
Sim. A partir de julho/2026 a Receita começa a emitir CPFs alfanuméricos (letras A-Z + dígitos nos 9 primeiros caracteres, os 2 últimos sempre dígitos). O algoritmo de módulo 11 continua, mas opera sobre o valor ASCII-48 de cada caractere (A=17, B=18, etc). Sua função de geração deve ser atualizada para escolher aleatoriamente entre [0-9A-Z] nas 9 primeiras posições.
Como gerar 10 mil CPFs rapidamente sem duplicar?+
Para lotes pequenos, gere e filtre com Set. Para lotes grandes (100k+), considere gerar sequencialmente partindo de um número-base e calcular DVs — evita colisão garantidamente. Performance: gerar 10 mil CPFs com módulo 11 leva ~50ms em Node moderno; não vale otimizar prematuramente.
Existe alguma biblioteca pronta em vez de implementar?+
Sim. Em npm: cpf-cnpj-validator, @faker-js/faker (com locale pt_BR), brazilian-values, gerador-validador-de-cpf-e-cnpj. Para TypeScript, cpf-cnpj-validator tem tipos bem definidos. Para testes, @faker-js/faker é a escolha padrão porque já vem com gerador de nome + endereço + telefone em português.
Continue lendo
O que é CPF? Estrutura, Significado de Cada Dígito e Como Validar
Guia completo do CPF: estrutura, região fiscal, algoritmo de módulo 11 dos dígitos verificadores com passo a passo, validação local em JavaScript e o novo CPF alfanumérico.
CPF para Testes em Desenvolvimento (2026): Como Usar, LGPD e Boas Práticas
Guia completo de CPF em ambiente de testes: por que nunca usar real, como gerar em massa, conformidade com LGPD, ferramentas por linguagem e estratégias para equipes.
Algoritmo do Dígito Verificador do CPF: Módulo 11 Completo (2026)
Como funciona o algoritmo de módulo 11 do CPF passo a passo. Implementações em JavaScript, Python, Go, Java e SQL. Casos especiais, performance e o que muda com o novo CPF alfanumérico.
Dados Fictícios para Testes de Software (2026): Ferramentas, Estratégias e LGPD
Guia completo de dados fictícios em testes: por que nunca usar reais, bibliotecas por linguagem (Faker, etc.), factories, seed determinístico e conformidade com LGPD.