Código
Validar e gerar CPF em código
A mesma função de validação (11 dígitos, sem sequência repetida, dois dígitos verificadores pelo módulo 11) pronta em JavaScript, TypeScript, Python, PHP, Java, C#.
Funciona igual no Node e no navegador. Não depende de nenhum pacote.
Validação
export function validarCPF(valor) {
const cpf = String(valor ?? '').replace(/\D/g, '');
// Precisa ter 11 dígitos e não pode ser uma sequência repetida.
// Atenção: 111.111.111-11 passa no módulo 11, por isso o teste explícito.
if (cpf.length !== 11) return false;
if (/^(\d)\1{10}$/.test(cpf)) return false;
// Peso posicional: com n = 9 os pesos vão de 10 a 2; com n = 10, de 11 a 2.
const dv = (n) => {
let soma = 0;
for (let i = 0; i < n; i++) soma += Number(cpf[i]) * (n + 1 - i);
const resto = soma % 11;
return resto < 2 ? 0 : 11 - resto;
};
return dv(9) === Number(cpf[9]) && dv(10) === Number(cpf[10]);
}Geração
export function gerarCPF() {
const base = Array.from({ length: 9 }, () => Math.floor(Math.random() * 10));
const dv = (digitos) => {
const soma = digitos.reduce((acc, d, i) => acc + d * (digitos.length + 1 - i), 0);
const resto = soma % 11;
return resto < 2 ? 0 : 11 - resto;
};
const d1 = dv(base);
const d2 = dv([...base, d1]);
return [...base, d1, d2].join('');
}Uso
validarCPF('111.444.777-35'); // true
validarCPF('111.111.111-11'); // false
gerarCPF(); // '52998224725'Mesma lógica do JavaScript, com os tipos declarados.
Validação
export function validarCPF(valor: string | null | undefined): boolean {
const cpf = String(valor ?? '').replace(/\D/g, '');
if (cpf.length !== 11) return false;
if (/^(\d)\1{10}$/.test(cpf)) return false;
const dv = (n: number): number => {
let soma = 0;
for (let i = 0; i < n; i++) soma += Number(cpf[i]) * (n + 1 - i);
const resto = soma % 11;
return resto < 2 ? 0 : 11 - resto;
};
return dv(9) === Number(cpf[9]) && dv(10) === Number(cpf[10]);
}Geração
export function gerarCPF(): string {
const base: number[] = Array.from({ length: 9 }, () =>
Math.floor(Math.random() * 10),
);
const dv = (digitos: number[]): number => {
const soma = digitos.reduce((acc, d, i) => acc + d * (digitos.length + 1 - i), 0);
const resto = soma % 11;
return resto < 2 ? 0 : 11 - resto;
};
const d1 = dv(base);
const d2 = dv([...base, d1]);
return [...base, d1, d2].join('');
}Uso
validarCPF('111.444.777-35'); // true
validarCPF(null); // false
gerarCPF(); // '52998224725'Só biblioteca padrão. Testado em Python 3.9+.
Validação
import re
def validar_cpf(valor: str) -> bool:
cpf = re.sub(r"\D", "", str(valor or ""))
# 11 dígitos e nada de sequências repetidas — elas passam no módulo 11.
if len(cpf) != 11 or cpf == cpf[0] * 11:
return False
# Peso posicional: n=9 usa pesos de 10 a 2; n=10, de 11 a 2.
def dv(n: int) -> int:
soma = sum(int(cpf[i]) * (n + 1 - i) for i in range(n))
resto = soma % 11
return 0 if resto < 2 else 11 - resto
return dv(9) == int(cpf[9]) and dv(10) == int(cpf[10])Geração
import random
def gerar_cpf() -> str:
base = [random.randint(0, 9) for _ in range(9)]
def dv(digitos: list[int]) -> int:
soma = sum(d * (len(digitos) + 1 - i) for i, d in enumerate(digitos))
resto = soma % 11
return 0 if resto < 2 else 11 - resto
d1 = dv(base)
d2 = dv(base + [d1])
return "".join(map(str, base + [d1, d2]))Uso
validar_cpf("111.444.777-35") # True
validar_cpf("111.111.111-11") # False
gerar_cpf() # '52998224725'PHP 7.4+. Sem dependência de extensão além da PCRE, que já vem habilitada.
Validação
<?php
function validarCpf(?string $valor): bool
{
$cpf = preg_replace('/\D/', '', (string) $valor);
// 11 dígitos e nada de sequências repetidas.
if (strlen($cpf) !== 11 || preg_match('/^(\d)\1{10}$/', $cpf)) {
return false;
}
// Peso posicional: n=9 usa pesos de 10 a 2; n=10, de 11 a 2.
$dv = static function (int $n) use ($cpf): int {
$soma = 0;
for ($i = 0; $i < $n; $i++) {
$soma += (int) $cpf[$i] * ($n + 1 - $i);
}
$resto = $soma % 11;
return $resto < 2 ? 0 : 11 - $resto;
};
return $dv(9) === (int) $cpf[9] && $dv(10) === (int) $cpf[10];
}Geração
<?php
function gerarCpf(): string
{
$base = [];
for ($i = 0; $i < 9; $i++) {
$base[] = random_int(0, 9);
}
$dv = static function (array $digitos): int {
$soma = 0;
$total = count($digitos);
foreach ($digitos as $i => $d) {
$soma += $d * ($total + 1 - $i);
}
$resto = $soma % 11;
return $resto < 2 ? 0 : 11 - $resto;
};
$d1 = $dv($base);
$d2 = $dv(array_merge($base, [$d1]));
return implode('', array_merge($base, [$d1, $d2]));
}Uso
validarCpf('111.444.777-35'); // true
validarCpf('111.111.111-11'); // false
gerarCpf(); // '52998224725'Java 8+. Repare no `\\D` com duas barras: em Java a regex vive dentro de uma String.
Validação
public final class Cpf {
private Cpf() {
}
public static boolean valido(String valor) {
if (valor == null) {
return false;
}
String cpf = valor.replaceAll("\\D", "");
// 11 dígitos e nada de sequências repetidas.
if (cpf.length() != 11 || cpf.chars().distinct().count() == 1) {
return false;
}
return dv(cpf, 9) == cpf.charAt(9) - '0'
&& dv(cpf, 10) == cpf.charAt(10) - '0';
}
// Peso posicional: n=9 usa pesos de 10 a 2; n=10, de 11 a 2.
private static int dv(String cpf, int n) {
int soma = 0;
for (int i = 0; i < n; i++) {
soma += (cpf.charAt(i) - '0') * (n + 1 - i);
}
int resto = soma % 11;
return resto < 2 ? 0 : 11 - resto;
}
}Geração
import java.security.SecureRandom;
public final class GeradorCpf {
private static final SecureRandom RANDOM = new SecureRandom();
private GeradorCpf() {
}
public static String gerar() {
int[] digitos = new int[11];
for (int i = 0; i < 9; i++) {
digitos[i] = RANDOM.nextInt(10);
}
digitos[9] = dv(digitos, 9);
digitos[10] = dv(digitos, 10);
StringBuilder sb = new StringBuilder(11);
for (int d : digitos) {
sb.append(d);
}
return sb.toString();
}
private static int dv(int[] digitos, int n) {
int soma = 0;
for (int i = 0; i < n; i++) {
soma += digitos[i] * (n + 1 - i);
}
int resto = soma % 11;
return resto < 2 ? 0 : 11 - resto;
}
}Uso
Cpf.valido("111.444.777-35"); // true
Cpf.valido("111.111.111-11"); // false
GeradorCpf.gerar(); // "52998224725"C# 8+ / .NET Core 3.1+. Use `RandomNumberGenerator` se precisar de aleatoriedade criptográfica.
Validação
using System;
using System.Linq;
using System.Text.RegularExpressions;
public static class Cpf
{
public static bool Valido(string valor)
{
if (string.IsNullOrWhiteSpace(valor))
return false;
var cpf = Regex.Replace(valor, @"\D", "");
// 11 dígitos e nada de sequências repetidas.
if (cpf.Length != 11 || cpf.Distinct().Count() == 1)
return false;
return Dv(cpf, 9) == cpf[9] - '0'
&& Dv(cpf, 10) == cpf[10] - '0';
}
// Peso posicional: n=9 usa pesos de 10 a 2; n=10, de 11 a 2.
private static int Dv(string cpf, int n)
{
var soma = 0;
for (var i = 0; i < n; i++)
soma += (cpf[i] - '0') * (n + 1 - i);
var resto = soma % 11;
return resto < 2 ? 0 : 11 - resto;
}
}Geração
using System;
using System.Linq;
public static class GeradorCpf
{
private static readonly Random Random = new Random();
public static string Gerar()
{
var digitos = new int[11];
for (var i = 0; i < 9; i++)
digitos[i] = Random.Next(10);
digitos[9] = Dv(digitos, 9);
digitos[10] = Dv(digitos, 10);
return string.Concat(digitos);
}
private static int Dv(int[] digitos, int n)
{
var soma = 0;
for (var i = 0; i < n; i++)
soma += digitos[i] * (n + 1 - i);
var resto = soma % 11;
return resto < 2 ? 0 : 11 - resto;
}
}Uso
Cpf.Valido("111.444.777-35"); // true
Cpf.Valido("111.111.111-11"); // false
GeradorCpf.Gerar(); // "52998224725"Os dois pontos em que essas funções costumam quebrar
Toda implementação de CPF erra nos mesmos dois lugares, e as duas armadilhas estão tratadas no código acima:
- Resto 0 ou 1. Quando o resto da divisão por 11 é menor que 2, o dígito verificador é
0, e não11 - resto, que daria 10 ou 11. Pular essa regra faz o validador rejeitar cerca de um terço dos CPFs legítimos. - Dígitos repetidos.
111.111.111-11e as outras nove sequências iguais passam na conta do módulo 11. Como são exatamente o que se digita para testar um formulário, precisam de uma verificação à parte.
A explicação completa da aritmética, com exemplo resolvido dígito a dígito, está emcomo validar um CPF.
Números para testar
Para exercitar a função com dados de verdade, o gerador produz até 1000 CPFs válidos por vez e exporta em .txt, .csv ou .json, pronto para virar fixture do seu conjunto de testes.
Casos que vale incluir na suíte: 111.444.777-35 (válido),111.111.111-11 (repetido, deve falhar), 123 (curto demais) e uma string vazia.