cnpjcpf.
Código · PHP

Validar CNPJ em PHP

Uma só função valida o CNPJ numérico e o novo alfanumérico: a conversão ASCII−48 é retrocompatível, então o mesmo módulo 11 serve para os dois.

A função

Uma só função valida o CNPJ numérico e o alfanumérico de 2026. O segredo é que cada caractere da base entra no módulo 11 como ord($c) - 48: assim '0'..'9' viram 0..9 (retrocompatível) e 'A'..'Z' viram 17..42.

PHP
function isValidCnpj(string $cnpj): bool {
    $cnpj = strtoupper(preg_replace('/[.\/-]/', '', $cnpj));
    if (!preg_match('/^[A-Z0-9]{12}\d{2}$/', $cnpj)) return false;
    if (preg_match('/^(.)\1{13}$/', $cnpj)) return false; // repetidos
    $w1 = [5,4,3,2,9,8,7,6,5,4,3,2];
    $w2 = [6,5,4,3,2,9,8,7,6,5,4,3,2];
    $dv = function (string $base, array $w): int {
        $s = 0;
        foreach ($w as $i => $p) $s += (ord($base[$i]) - 48) * $p;
        $r = $s % 11; return $r < 2 ? 0 : 11 - $r;
    };
    $d1 = $dv(substr($cnpj, 0, 12), $w1);
    $d2 = $dv(substr($cnpj, 0, 12) . $d1, $w2);
    return $d1 === (int)$cnpj[12] && $d2 === (int)$cnpj[13];
}

var_dump(isValidCnpj('11.222.333/0001-81')); // true  (numérico)
var_dump(isValidCnpj('12ABC34501DE35'));     // true  (alfanumérico, exemplo SERPRO)
var_dump(isValidCnpj('11.222.333/0001-00')); // false

O mesmo código valida os dois formatos: o numérico é um caso particular do alfanumérico. A base tem 12 posições (letras A–Z ou dígitos 0–9) e os 2 verificadores são sempre numéricos — por isso a regex termina em \d{2}.

Por que ord − 48

No módulo 11 cada posição vira um número antes de multiplicar pelo peso. Para tratar letra e dígito de forma uniforme, converte-se o caractere pelo seu código ASCII menos 48: '0' vira 0, '9' vira 9 e 'A' vira 17 (segue até 'Z' = 42). É exatamente o que ord($base[$i]) - 48 faz na soma. Os pesos vêm em duas listas ($w1 para o 1º dígito, $w2 para o 2º) e o resto da divisão por 11 define o verificador — $r < 2 ? 0 : 11 - $r. É o módulo 11 de sempre, só com a entrada normalizada.

A base oficial do SERPRO 12ABC34501DE produz DV 35: no 1º dígito a soma dá 459 (resto 8 → 11 - 8 = 3) e no 2º a soma dá 424 (resto 6 → 11 - 6 = 5). Detalhe do cálculo em calcular o dígito verificador alfanumérico.

publicidade

Cuidados

  • Regex só valida formato. Um padrão como /^[A-Z0-9]{12}\d{2}$/ confirma que são 12 posições alfanuméricas + 2 dígitos, mas não confere o verificador — quem faz isso é a função acima. Veja regex de CNPJ.
  • Sequências repetidas (00000000000000) passariam no módulo 11, por isso a função as descarta antes com /^(.)\1{13}$/.
  • Só maiúsculas. O alfanumérico não aceita minúsculas — por isso a função faz strtoupper() e remove . / - antes de validar.
  • No banco, use texto. Colunas numéricas (BIGINT) quebram com letras — guarde em CHAR(14)/VARCHAR.
  • Válido ≠ existe. A função confirma a consistência matemática, não se o CNPJ foi emitido a uma empresa real: CNPJ válido vs. CNPJ real.
  • Alfanumérico entra em jul/2026 (IN RFB nº 2.229/2024), só para novos registros. O código já está pronto para os dois formatos.

Continue

Código verificado por execução, inclusive contra o exemplo oficial do SERPRO (12ABC34501DE → DV 35). Algoritmo módulo 11 com ASCII−48. Revisado em 06/2026.