O Gerador De CPF O Gerador De CPF

Gerar CPF em Laravel: Service, Factory e Artisan

O gerador online de CPF resolve testes manuais, mas projetos Laravel pedem integração nativa: factories, seeders e comandos Artisan que produzam CPFs válidos sob demanda. A lógica segue o algoritmo de módulo 11 e o artigo foca na integração com o framework.

Service

<?php

namespace App\Services;

class CpfGenerator
{
    public static function generate(): 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);
    }

    public static function validate(string $cpf): bool
    {
        $cleaned = preg_replace('/[^\d]/', '', $cpf);

        if (strlen($cleaned) !== 11) {
            return false;
        }

        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;
    }
}

Factory

<?php

namespace Database\Factories;

use App\Models\User;
use App\Services\CpfGenerator;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;

/**
 * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\User>
 */
class UserFactory extends Factory
{
    protected $model = User::class;

    public function definition(): array
    {
        return [
            'name'              => fake()->name(),
            'email'             => fake()->unique()->safeEmail(),
            'cpf'               => CpfGenerator::generate(),
            'email_verified_at' => now(),
            'password'          => Hash::make('password'),
            'remember_token'    => Str::random(10),
        ];
    }
}

Com essa factory configurada, basta chamar User::factory()->create() em seeders ou testes para obter um usuário com CPF válido. Para gerar múltiplos registros: User::factory()->count(50)->create().

Comando Artisan

<?php

namespace App\Console\Commands;

use App\Services\CpfGenerator;
use Illuminate\Console\Command;

class GenerateCpf extends Command
{
    protected $signature = 'cpf:generate {quantidade=1 : Quantidade de CPFs a gerar}';

    protected $description = 'Gera CPFs válidos para teste';

    public function handle(): int
    {
        $quantidade = (int) $this->argument('quantidade');

        if ($quantidade < 1) {
            $this->error('A quantidade deve ser pelo menos 1.');
            return Command::FAILURE;
        }

        $this->info("Gerando {$quantidade} CPF(s):");
        $this->newLine();

        for ($i = 0; $i < $quantidade; $i++) {
            $cpf = CpfGenerator::generate();
            $this->line($cpf);
        }

        return Command::SUCCESS;
    }
}

Uso: php artisan cpf:generate 10 gera dez CPFs válidos no terminal. Sem argumento, gera apenas um.

Análise do código

A classe CpfGenerator centraliza toda a lógica em métodos estáticos. O método generate() cria nove dígitos aleatórios com rand(0, 9), calcula o primeiro dígito verificador somando cada dígito multiplicado pelo peso correspondente (10 a 2) e aplicando módulo 11, depois repete o processo com dez dígitos (pesos de 11 a 2) para obter o segundo verificador. O método validate() faz o caminho inverso, recalculando os verificadores para confirmar a integridade do CPF.

A integração com Model Factory é direta: chamar CpfGenerator::generate() dentro do método definition() garante que cada registro criado por User::factory() receba um CPF válido. Isso é especialmente útil em testes de feature que dependem de validação de CPF no FormRequest, pois os dados de fábrica já passam nas regras de validação sem ajustes manuais.

O comando Artisan cpf:generate expõe a geração via terminal usando a mesma Service class. O argumento quantidade tem valor padrão 1, validação para evitar valores negativos e retorna Command::SUCCESS ou Command::FAILURE seguindo as convenções do Laravel. Isso permite gerar CPFs rapidamente durante o desenvolvimento sem precisar abrir o tinker ou criar scripts avulsos.

Testes

<?php

namespace Tests\Unit\Services;

use App\Services\CpfGenerator;
use PHPUnit\Framework\TestCase;

class CpfGeneratorTest extends TestCase
{
    public function testGeradoDeveTer11DigitosValidos(): void
    {
        $cpf = CpfGenerator::generate();

        $this->assertSame(11, strlen($cpf));
        $this->assertMatchesRegularExpression('/^\d{11}$/', $cpf);
        $this->assertTrue(CpfGenerator::validate($cpf));
    }

    public function testFactoryCriaUsuarioComCpfValido(): void
    {
        $cpf = CpfGenerator::generate();

        $this->assertTrue(
            CpfGenerator::validate($cpf),
            "CPF gerado pela service deve ser válido: {$cpf}"
        );
    }

    public function testMultiplosGeradosDevemDiferir(): void
    {
        $cpf1 = CpfGenerator::generate();
        $cpf2 = CpfGenerator::generate();
        $cpf3 = CpfGenerator::generate();

        $this->assertFalse(
            $cpf1 === $cpf2 && $cpf2 === $cpf3,
            'Três CPFs gerados consecutivamente não devem ser todos iguais'
        );
    }
}

O primeiro teste garante que o CPF gerado tem exatamente 11 caracteres numéricos e passa na validação da própria service. O segundo confirma que CPFs produzidos pelo mesmo método usado na factory são válidos. 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 Laravel com Custom Rule e FormRequest, ou volte à página inicial para gerar CPFs online.