andrehenrique311085-debug

O dia 31 de julho de 2026 marca a maior mudança no CNPJ desde que ele existe: novas empresas podem receber CNPJs com letras, tipo 12.ABC.345/01DE-35. Se o seu sistema cadastra clientes ou fornecedores, isso afeta você — mesmo que nenhum cliente seu tenha CNPJ novo ainda.

O que mudou de verdade

A IN RFB nº 2.229/2024 definiu que as 12 primeiras posições do CNPJ (raiz + ordem) passam a aceitar 0-9 e A-Z. Os 2 dígitos verificadores continuam numéricos. CNPJs existentes não mudam — os dois formatos coexistem.

O que quebra em sistemas legados:

  • Coluna BIGINT/NUMERIC no banco → não salva letras
  • ^\d{14}$ no validador → rejeita CNPJ válido
  • parseInt(cnpj) → corrompe silenciosamente
  • Máscara 99.999.999/9999-99 no form → usuário não consegue digitar

O algoritmo (é mais simples do que parece)

O cálculo do DV continua sendo o velho módulo 11. A única mudança: cada caractere entra com o valor ASCII − 48. Dígitos mantêm o valor deles ('0'→0 … '9'→9) e letras valem 17 a 42 ('A'→17 … 'Z'→42). Para CNPJs só numéricos o resultado é idêntico ao algoritmo antigo — por isso a compatibilidade é total.

function checkDigits(base12) {
  const W1 = [5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2];
  const W2 = [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2];
  const val = (ch) => ch.charCodeAt(0) - 48; // '0'-'9' → 0-9, 'A'-'Z' → 17-42

  const dv = (chars, weights) => {
    const sum = chars.reduce((acc, ch, i) => acc + val(ch) * weights[i], 0);
    const rest = sum % 11;
    return rest < 2 ? 0 : 11 - rest;
  };

  const c = base12.split("");
  const dv1 = dv(c, W1);
  const dv2 = dv([...c, String(dv1)], W2);
  return `${dv1}${dv2}`;
}

checkDigits("12ABC34501DE"); // "35" — exemplo oficial da Receita ✔

Enter fullscreen mode Exit fullscreen mode

Validar é: normalizar (tirar máscara, maiúsculas), checar ^[0-9A-Z]{12}[0-9]{2}$, rejeitar repetidos, e conferir os DVs.

Não quero copiar código, quero uma lib

Publiquei o validador completo (validação, formatação, geração de massa de teste e um explain() que mostra o passo a passo do cálculo) como pacote open-source, zero dependências, UMD (Node + navegador):

npm install valida-cnpj-alfanumerico

Enter fullscreen mode Exit fullscreen mode

const CNPJ = require("valida-cnpj-alfanumerico");
CNPJ.isValid("12.ABC.345/01DE-35"); // true
CNPJ.generate({ alphanumeric: true, masked: true }); // massa de teste válida

Enter fullscreen mode Exit fullscreen mode

E se você usa GitHub Actions, dá para barrar regressões direto no PR com a action cnpj-scan — ela detecta colunas numéricas, regex só-dígitos e conversões perigosas no seu código.

Ferramentas online (grátis)

Se você só quer validar/gerar sem instalar nada — ou passar um link para o time de QA:

E se você precisa descobrir onde o seu codebase quebra, o cnpj-scan varre o código atrás dos padrões perigosos (colunas numéricas, regex só-dígitos, conversões) e roda 100% local: https://cnpjcomletras.com.br/diagnostico


Curtiu? O exemplo oficial da Receita (12.ABC.345/01DE-35) valida no seu sistema hoje? Testa lá e me conta nos comentários.