bateCarimbo.
Regras

CNPJ alfanumérico: o guia completo do formato em vigor desde julho de 2026

O CNPJ alfanumérico já está valendo para novas inscrições. Veja o que mudou na prática, como fica o cálculo do dígito verificador com letras, o exemplo oficial resolvido e o checklist de adequação para sistemas legados.

Por · Publicado em · Revisado em · 11 min de leitura

Desde julho de 2026, as novas inscrições no Cadastro Nacional da Pessoa Jurídica saem no formato alfanumérico: a raiz e a ordem do estabelecimento aceitam letras de A a Z além dos algarismos. Foi a maior alteração na estrutura do documento desde a criação do cadastro, e continua derrubando integrações em sistemas que trataram CNPJ como número. Este guia mostra o que mudou, como o dígito verificador passou a ser calculado e o que ainda precisa ser revisado num sistema legado.

A estrutura do CNPJ, posição por posição

São catorze posições em três blocos. As oito primeiras formam a raiz, que identifica a empresa. As quatro seguintes são a ordem do estabelecimento — 0001 na matriz, valores crescentes nas filiais. As duas últimas são os dígitos verificadores, calculados por módulo 11 sobre as doze anteriores. Matriz e filiais compartilham a raiz e diferem só na ordem.

Essa divisão não mudou, e a máscara também não: continua XX.XXX.XXX/XXXX-XX, com os mesmos pontos, a mesma barra e o mesmo hífen. O que mudou foi o alfabeto aceito em cada posição.

O que mudou na prática

As doze posições da base passaram a aceitar 0-9 e A-Z maiúsculo. Os dois dígitos verificadores permaneceram sempre numéricos. Um CNPJ alfanumérico tem esta cara: 12.ABC.345/01DE-35.

Nenhuma empresa trocou de número. Os CNPJs emitidos antes da mudança seguem válidos por tempo indeterminado e nunca serão convertidos, o que tem uma consequência prática desconfortável: não existe data de corte depois da qual o formato numérico deixa de circular. Os dois convivem em produção, misturados no mesmo banco, na mesma fila e no mesmo arquivo de integração — o suporte ao legado é permanente, não transitório.

Vale registrar o que ficou igual, porque é o que evita retrabalho: o comprimento seguiu em catorze caracteres, a máscara é a mesma, a separação entre raiz e ordem é a mesma, filiais continuam diferindo da matriz apenas no bloco da ordem e os dois últimos caracteres continuam sendo dígitos. Quem já guardava o documento como texto de catorze posições, sem máscara, tem quase nada a fazer além do cálculo do DV.

O motivo da mudança é aritmético. Com oito posições numéricas, a raiz oferece 108 combinações, cerca de cem milhões, das quais boa parte já foi consumida em décadas de aberturas, baixas e reservas. Com 36 símbolos por posição, o mesmo campo passa a 368, algo em torno de 2,8 trilhões de combinações. O formato do documento foi preservado e o espaço de numeração deixou de ser um problema de curto prazo.

A tabela de conversão de caracteres

Para que o módulo 11 continuasse funcionando, cada caractere precisou de um valor numérico. A regra adotada é o código ASCII menos 48. Como '0' vale 48 no ASCII, os algarismos mapeiam para eles mesmos — 0 continua 0, 9 continua 9. As letras começam em A, que é 65 no ASCII e portanto vale 17, e seguem sem interrupção até Z, que vale 42. Repare no salto de 9 para 17: as sete posições ASCII entre 9 e A são ocupadas por outros símbolos e ficam de fora da tabela.

Valor de cada caractere na conta do dígito verificador (ASCII − 48)
CaractereValorCaractereValorCaractereValor
00C19O31
11D20P32
22E21Q33
33F22R34
44G23S35
55H24T36
66I25U37
77J26V38
88K27W39
99L28X40
A17M29Y41
B18N30Z42

A elegância da escolha está aí: como os algarismos mapeiam para si mesmos, a mesma rotina serve para os dois formatos. Não é preciso um caminho de código para CNPJ antigo e outro para CNPJ novo.

O exemplo oficial resolvido

O exemplo divulgado pela Receita Federal e pelo SERPRO é 12.ABC.345/01DE-35. A base é 12ABC34501DE e os pesos são os mesmos de sempre: 2 a 9 ciclicamente, da direita para a esquerda. Para os doze caracteres da base, isso resulta em 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3 e 2 na leitura da esquerda para a direita.

Primeiro dígito verificador de 12ABC34501DE
CaractereValorPesoProduto
1155
2248
A17351
B18236
C199171
33824
44728
55630
0050
1144
D20360
E21242
Soma459

459 ÷ 11 → resto 8

Resto 8, maior ou igual a 2, então o dígito é 11 − 8.

Dígito verificador = 3

O segundo dígito repete a conta sobre treze caracteres — a base mais o dígito recém-obtido —, o que empurra todos os pesos uma casa e adiciona o peso 6 no início:

Segundo dígito verificador de 12ABC34501DE3
CaractereValorPesoProduto
1166
22510
A17468
B18354
C19238
33927
44832
55735
0060
1155
D20480
E21363
3326
Soma424

424 ÷ 11 → resto 6

Resto 6, maior ou igual a 2, então o dígito é 11 − 6.

Dígito verificador = 5

Daí o sufixo -35. A regra do resto continua idêntica à do CPF e dos demais documentos de módulo 11: resto 0 ou 1 produz dígito 0, qualquer outro resto produz 11 − resto.

Validando os dois formatos em TypeScript

A implementação abaixo aceita numérico e alfanumérico com um único cálculo. Os dois detalhes que costumam passar despercebidos são a normalização (remover a máscara e passar para maiúsculas, já que 'a' vale 97 no ASCII e produziria 49 em vez de 17) e a distinção entre os dois formatos apenas na expressão regular de estrutura.

TypeScript
const NUMERIC = /^\d{14}$/;
const ALPHANUMERIC = /^[0-9A-Z]{12}\d{2}$/;
const WEIGHTS = [2, 3, 4, 5, 6, 7, 8, 9];

// '0'-'9' -> 0-9 ; 'A'-'Z' -> 17-42
const charValue = (char: string) => char.charCodeAt(0) - 48;

function checkDigit(base: string): number {
  let sum = 0;
  for (let i = base.length - 1, w = 0; i >= 0; i--, w++) {
    sum += charValue(base[i]) * WEIGHTS[w % 8];
  }
  const remainder = sum % 11;
  return remainder < 2 ? 0 : 11 - remainder;
}

export function isValidCnpj(input: string): boolean {
  const cnpj = input.replace(/[.\-/]/g, "").toUpperCase();

  if (!NUMERIC.test(cnpj) && !ALPHANUMERIC.test(cnpj)) return false;
  if (/^(\d)\1{13}$/.test(cnpj)) return false; // 00000000000000 e afins

  const base = cnpj.slice(0, 12);
  const first = checkDigit(base);
  const second = checkDigit(`${base}${first}`);

  return cnpj.slice(12) === `${first}${second}`;
}

isValidCnpj("12.ABC.345/01DE-35"); // true
isValidCnpj("11.222.333/0001-81"); // true
isValidCnpj("12.ABC.345/01DE-34"); // false
Uma rotina só para os dois formatos: os algarismos mapeiam para si mesmos na conversão ASCII − 48.

Versões comentadas em outras linguagens, com os casos de teste equivalentes, estão nos guias de validação em JavaScript e TypeScript e de validação em Python, Java e C#.

Mensagens de erro que vale separar

Um booleano resolve a validação, mas atende mal quem está digitando. Com dois formatos em circulação, quatro situações de recusa têm causas diferentes e merecem mensagens diferentes:

  • Comprimento errado depois de remover a máscara. Quase sempre é um caractere a mais ou a menos na digitação, não um documento inexistente.
  • Caractere fora do conjunto permitido. Acentos, cedilha ou espaço no meio indicam texto colado de outro sistema. Aqui a mensagem útil diz o conjunto aceito: 0-9 e A-Z nas doze primeiras posições.
  • Letra em um dos dois dígitos verificadores. Esse é o erro novo, e o mais confuso para o usuário, que viu letras no começo do número e supôs que elas valessem em qualquer posição.
  • Dígito verificador incorreto. Estrutura certa, conta errada. Vale dizer isso explicitamente, porque muda o que a pessoa deve conferir: o número em si, e não o jeito de digitá-lo.

No formato numérico ainda cabe a recusa explícita das sequências repetidas, do tipo 00.000.000/0000-00, rejeitadas por convenção mesmo quando a conta fecha. É uma guarda extra, não parte do módulo 11, e continua valendo só para o formato antigo.

Exibição e conferência humana

O conjunto de caracteres vai de A a Z sem exclusões, então O e 0, I e 1, S e 5 podem aparecer no mesmo documento. Quem lê um CNPJ em voz alta ao telefone ou confere um número impresso perde a pista que os catorze algarismos davam. Em telas de conferência, uma fonte monoespaçada com zero cortado e a máscara sempre aplicada reduzem bastante o ruído; em comprovantes, separar visualmente os blocos ajuda mais do que aumentar o corpo da fonte.

Do lado da entrada, aceite o que o usuário colar e normalize por conta própria: minúsculas, espaços nas pontas, máscara parcial, máscara completa. Rejeitar por causa de um espaço colado junto é a forma mais fácil de transformar uma mudança de formato em chamado de suporte.

Checklist de adequação para sistemas legados

A adaptação costuma ser rasa em dificuldade e larga em superfície: são muitos pontos pequenos espalhados pela aplicação. Os que mais aparecem:

  • Tipo da coluna. CNPJ guardado em integer, bigint ou numeric já era arriscado por causa dos zeros à esquerda; com letras, simplesmente não entra. A coluna precisa ser char(14) ou varchar(14). O guia de validação no banco de dados traz as funções e as restrições CHECK correspondentes.
  • Conversões implícitas para número. Procure por parseInt, Number(), ::bigint e equivalentes aplicados ao documento. parseInt em 12ABC34501DE35 devolve 12 em silêncio, sem erro e sem aviso — é o tipo de falha que só aparece em produção.
  • Expressões regulares. Todo \d{14} precisa virar uma alternativa entre os dois formatos, com os dois últimos caracteres presos a dígitos. Padrões prontos para os demais documentos estão no guia de expressões regulares de documentos brasileiros.
  • Normalização de entrada. Antes de calcular o DV, remova a máscara e aplique toUpperCase(). Sem isso, um usuário que digita minúsculas recebe "CNPJ inválido" para um documento correto.
  • Campos de formulário. Máscaras que bloqueiam teclas não numéricas passam a rejeitar letras legítimas, e inputmode="numeric" abre o teclado errado no celular. Os dois últimos caracteres continuam numéricos, então a máscara pode ser mista.
  • Ordenação e comparação. Uma coluna de texto ordena por ASCII, e os algarismos vêm antes das letras. Relatórios que agrupavam por faixa numérica de CNPJ precisam de outro critério; comparações devem ser feitas sempre sobre a forma normalizada, nunca sobre a mascarada.
  • Arquivos de largura fixa e integrações. O tamanho não mudou, então o leiaute cabe. O que quebra são os parsers que interpretam o campo como inteiro e os bancos intermediários com coluna numérica no caminho. Vale rodar um lote alfanumérico ponta a ponta, incluindo os sistemas de terceiros.
  • Buscas e índices. Se a coluna passar de numérica para texto, o índice muda de natureza e consultas por prefixo de raiz precisam usar comparação de texto. Guardar também a forma normalizada, sem máscara e em maiúsculas, em coluna própria evita busca com LIKE sobre o valor formatado.
  • Chaves de cache e deduplicação. Se em algum ponto o sistema usa o CNPJ como chave, a normalização precisa ser idêntica em todos eles. Uma rotina que passa para maiúsculas e outra que não passa produzem duas entradas para a mesma empresa.
  • Testes. Fixtures que só contêm CNPJs numéricos passam a dar falsa sensação de cobertura. Cada caso de teste de CNPJ merece um par alfanumérico ao lado, e ao menos um caso negativo com letra nos dígitos verificadores.

Gerando massa de teste com os dois formatos

Nenhum desses pontos é verificável sem dados. O gerador de CNPJ do bateCarimbo produz lotes nos dois formatos, com dígitos verificadores calculados pela mesma regra descrita aqui, e valida uma lista colada de uma vez informando qual formato foi detectado em cada linha. Para cenários que precisam de razão social, endereço e demais campos coerentes, o gerador de empresas monta a ficha inteira. Como organizar essas fixtures no repositório é assunto do guia de massa de dados de teste. Todos os documentos gerados são fictícios e existem para exercitar código, não para representar empresas reais.

Fontes e referências