Gerar CPF em PHP: Função com Testes PHPUnit
Sistemas PHP frequentemente precisam gerar CPFs válidos para seeds de banco, testes funcionais e ambientes de staging. As funções abaixo aplicam o algoritmo de módulo 11 sobre nove dígitos aleatórios de forma simples e direta, incluindo um validador auxiliar para confirmar a integridade do resultado.
Código
<?php
function geraCPF(): string
{
$digits = [];
for ($i = 0; $i < 9; $i++) {
$digits[] = rand(0, 9);
}
// Primeiro dígito verificador
$sum = 0;
for ($i = 0; $i < 9; $i++) {
$sum += $digits[$i] * (10 - $i);
}
$r = $sum % 11;
$digits[] = $r < 2 ? 0 : 11 - $r;
// Segundo dígito verificador
$sum = 0;
for ($i = 0; $i < 10; $i++) {
$sum += $digits[$i] * (11 - $i);
}
$r = $sum % 11;
$digits[] = $r < 2 ? 0 : 11 - $r;
return implode('', $digits);
}
function validaCPF(string $cpf): bool
{
$cleaned = preg_replace('/[^\d]/', '', $cpf);
if (strlen($cleaned) !== 11) {
return false;
}
// Rejeita CPFs com todos os dígitos iguais
if (preg_match('/^(\d)\1{10}$/', $cleaned)) {
return false;
}
$digits = array_map('intval', str_split($cleaned));
// Verifica primeiro dígito
$sum = 0;
for ($i = 0; $i < 9; $i++) {
$sum += $digits[$i] * (10 - $i);
}
$r = $sum % 11;
$expected = $r < 2 ? 0 : 11 - $r;
if ($digits[9] !== $expected) {
return false;
}
// Verifica segundo dígito
$sum = 0;
for ($i = 0; $i < 10; $i++) {
$sum += $digits[$i] * (11 - $i);
}
$r = $sum % 11;
$expected = $r < 2 ? 0 : 11 - $r;
return $digits[10] === $expected;
}Análise do código
A função geraCPF() começa construindo um array com nove dígitos aleatórios usando rand(0, 9). O primeiro dígito verificador é calculado somando cada dígito base multiplicado pelo peso correspondente (10 a 2), aplicando o módulo 11 e convertendo o resto conforme a regra: se menor que 2 o verificador é zero, caso contrário é 11 menos o resto. O segundo verificador repete o processo com os dez dígitos (incluindo o primeiro verificador), usando pesos de 11 a 2.
A função validaCPF() faz o caminho inverso. Ela remove qualquer caractere não numérico com preg_replace, verifica se a string resultante tem exatamente 11 dígitos e rejeita sequências com todos os dígitos iguais (como 11111111111) usando uma expressão regular com referência retroativa. Depois converte cada caractere para inteiro com str_split e array_map, recalculando ambos os verificadores para comparação.
A escolha de implode('', $digits) para montar o resultado é idiomática em PHP e produz a string de 11 dígitos de forma concisa. O uso de intval na conversão garante comparações com === (tipo estrito), evitando falsos positivos que poderiam ocorrer com comparação frouxa entre strings e inteiros.
Uso
<?php
$cpf = geraCPF();
echo "CPF gerado: $cpf\n";
echo "Válido: " . (validaCPF($cpf) ? 'sim' : 'não') . "\n";Testes
<?php
use PHPUnit\Framework\TestCase;
class CPFGeneratorTest extends TestCase
{
public function testGeradoDeveTer11Digitos(): void
{
$cpf = geraCPF();
$this->assertSame(11, strlen($cpf));
$this->assertMatchesRegularExpression('/^\d{11}$/', $cpf);
}
public function testGeradoDeveSerValido(): void
{
$cpf = geraCPF();
$this->assertTrue(validaCPF($cpf));
}
public function testMultiplosGeradosDevemDiferir(): void
{
$cpf1 = geraCPF();
$cpf2 = geraCPF();
$cpf3 = geraCPF();
$this->assertFalse(
$cpf1 === $cpf2 && $cpf2 === $cpf3,
'Três CPFs gerados consecutivamente não devem ser todos iguais'
);
}
}O primeiro teste garante que o CPF tem exatamente 11 caracteres numéricos. O segundo confirma que o CPF gerado passa na validação. O terceiro gera três CPFs e verifica que não são todos idênticos, detectando falhas na aleatoriedade.
Veja também como validar CPF em PHP com exemplos detalhados, ou volte à página inicial para gerar CPFs online.