Pular para o conteúdo
ValidadorCNPJ Gerar CNPJ

PHP · código pronto

Validar CNPJ alfanumérico em PHP

Validador de CNPJ alfanumérico em PHP 8, sem dependências, com regra pronta para Laravel.

Testar um CNPJ agora Gerar massa de teste

PHP 8.0+ sem nenhuma dependência. Depois do algoritmo tem a Rule do Laravel, que é onde a maioria dos projetos PHP valida CNPJ na prática.

O algoritmo é sempre o mesmo: cada caractere vale o seu código ASCII menos 48 (0=0 … 9=9, A=17 … Z=42), os pesos vão de 2 a 9 da direita para a esquerda, soma-se tudo, divide-se por 11 e o dígito é 0 quando o resto é menor que 2, ou 11 menos o resto. Ver a conta detalhada.

Código completo

validação de CNPJ alfanumérico em PHP
<?php

declare(strict_types=1);

function cnpj_limpar(?string $valor): string
{
    return preg_replace('/[^0-9A-Z]/', '', strtoupper($valor ?? '')) ?? '';
}

/** Calcula um dígito do módulo 11 (valor do caractere = ASCII - 48). */
function cnpj_digito(string $sequencia): int
{
    $soma = 0;
    $tamanho = strlen($sequencia);

    for ($i = 0; $i < $tamanho; $i++) {
        $valor = ord($sequencia[$i]) - 48;
        $peso = (($tamanho - 1 - $i) % 8) + 2;
        $soma += $valor * $peso;
    }

    $resto = $soma % 11;

    return $resto < 2 ? 0 : 11 - $resto;
}

/** Devolve os dois dígitos verificadores da base de 12 caracteres. */
function cnpj_calcular_dv(string $base): string
{
    $primeiro = cnpj_digito($base);
    $segundo = cnpj_digito($base . $primeiro);

    return (string) $primeiro . (string) $segundo;
}

/** Valida CNPJ numérico ou alfanumérico, com ou sem máscara. */
function cnpj_valido(?string $valor): bool
{
    $cnpj = cnpj_limpar($valor);

    if (!preg_match('/^[0-9A-Z]{12}\d{2}$/', $cnpj)) {
        return false;
    }

    if (preg_match('/^(.)\1{13}$/', $cnpj)) {
        return false;
    }

    return cnpj_calcular_dv(substr($cnpj, 0, 12)) === substr($cnpj, 12);
}

/** Aplica a máscara 00.000.000/0000-00. */
function cnpj_formatar(string $valor): string
{
    $cnpj = cnpj_limpar($valor);

    if (strlen($cnpj) !== 14) {
        return $cnpj;
    }

    return sprintf(
        '%s.%s.%s/%s-%s',
        substr($cnpj, 0, 2),
        substr($cnpj, 2, 3),
        substr($cnpj, 5, 3),
        substr($cnpj, 8, 4),
        substr($cnpj, 12, 2)
    );
}

// Exemplo oficial da Receita Federal
var_dump(cnpj_calcular_dv('12ABC34501DE'));      // string(2) "35"
var_dump(cnpj_valido('12.ABC.345/01DE-35'));     // bool(true)
var_dump(cnpj_valido('11.222.333/0001-81'));     // bool(true)

Testes e integração com o framework

Laravel
<?php

namespace App\Rules;

use Closure;
use Illuminate\Contracts\Validation\ValidationRule;

class CnpjValido implements ValidationRule
{
    public function validate(string $atributo, mixed $valor, Closure $falhar): void
    {
        if (!is_string($valor) || !cnpj_valido($valor)) {
            $falhar('O campo :attribute não contém um CNPJ válido.');
        }
    }
}

// Uso no FormRequest
public function rules(): array
{
    return [
        'razao_social' => ['required', 'string', 'min:3'],
        'cnpj' => ['required', 'string', new CnpjValido()],
    ];
}

Detalhes que costumam quebrar em PHP

Casos de teste recomendados

Cubra pelo menos estes cenários — eles pegam praticamente todos os erros de implementação:

EntradaEsperadoO que testa
12.ABC.345/01DE-35válidoexemplo oficial, com máscara
12abc34501de35válidonormalização para maiúsculas
11.222.333/0001-81válidocompatibilidade com o formato numérico
11.222.333/0001-82inválidodígito verificador errado
12ABC34501DEABinválidoletra no dígito verificador
12ABC34501DE3inválidotamanho incorreto
00.000.000/0000-00inválidosequência repetida
"" / nullinválidoentrada vazia sem exceção

Precisa de mais massa de teste? O gerador produz até 500 CNPJs alfanuméricos válidos de uma vez, com opção de baixar em .txt.

O mesmo algoritmo em outras linguagens

Dúvidas sobre CNPJ alfanumérico em PHP

Preciso de alguma biblioteca para validar CNPJ alfanumérico em PHP?

Não. O código desta página usa apenas a biblioteca padrão de PHP — são cerca de 30 linhas. Bibliotecas de terceiros só valem a pena se você também precisa de formatação, geração e validação de outros documentos; e, nesse caso, confira se a versão instalada já suporta o formato alfanumérico.

A mesma função valida CNPJ numérico e alfanumérico em PHP?

Sim. Como o valor de cada dígito é o próprio dígito (código ASCII menos 48), o algoritmo alfanumérico produz o mesmo resultado do antigo para números. Você não precisa manter duas funções nem ramificar por formato.

Como testar se a implementação está certa?

Use o exemplo oficial da Receita Federal: a base 12ABC34501DE tem dígitos verificadores 35, formando 12.ABC.345/01DE-35. Confira também um CNPJ numérico conhecido, como 11.222.333/0001-81, e um inválido, como 11.222.333/0001-82.

O que mais precisa mudar além da função de validação?

O tipo da coluna no banco (de numérico para VARCHAR(14)), qualquer conversão para inteiro no caminho do dado, as máscaras de entrada e as regex espalhadas por validações e relatórios. A função de validação costuma ser a parte mais fácil da migração.