Como validar CNPJ alfanumérico em JavaScript
Função pronta em JavaScript puro (navegador e Node) para validar o novo CNPJ alfanumérico, calcular os dígitos verificadores e mascarar o input do formulário, com vetores de teste.
Quer validar o CNPJ alfanumérico em JavaScript sem dor de cabeça? Neste tutorial você leva uma função pronta — que normaliza, calcula os dígitos verificadores e valida — funcionando tanto no navegador quanto no Node.js, com nota para TypeScript e um exemplo de máscara em formulário. Tudo testado com os vetores oficiais.
O que muda no CNPJ alfanumérico
A partir de julho de 2026 (Instrução Normativa RFB nº 2.229/2024), o CNPJ passa a aceitar letras maiúsculas (A–Z) e dígitos (0–9) nas 12 primeiras posições — a raiz (8) e a ordem da filial (4). As duas últimas posições, os dígitos verificadores, continuam numéricas. O número segue com 14 posições e a mesma máscara XX.XXX.XXX/XXXX-DD. Os CNPJs numéricos atuais não mudam e seguem válidos, convivendo com os novos — por isso seu código precisa aceitar os dois formatos. Se quiser o panorama completo de migração, veja nosso guia de implementação do CNPJ alfanumérico.
Validando CNPJ alfanumérico em JavaScript
A função abaixo é a versão final que recomendamos. Ela usa normalizar() para tirar a máscara e forçar maiúsculas, digito() para aplicar o módulo 11 com os pesos corretos, calcularDV() para gerar os dois dígitos e validarCNPJ() para conferir formato, base não-zerada e os dígitos verificadores. É JavaScript puro: roda no navegador e no Node sem dependências.
// Valor de cada caractere = código ASCII - 48 ('0'=0..'9'=9, 'A'=17..'Z'=42)
const PESO1 = [5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2];
const PESO2 = [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2];
const normalizar = (s) => (s || '').toUpperCase().replace(/[^A-Z0-9]/g, '');
function digito(base, pesos) {
let soma = 0;
for (let i = 0; i < base.length; i++) soma += (base.charCodeAt(i) - 48) * pesos[i];
const resto = soma % 11;
return resto < 2 ? 0 : 11 - resto;
}
function calcularDV(base12) { // base12 = 12 primeiras posições
const d1 = digito(base12, PESO1);
const d2 = digito(base12 + d1, PESO2);
return `${d1}${d2}`;
}
function validarCNPJ(cnpj) {
const c = normalizar(cnpj);
if (!/^[A-Z0-9]{12}[0-9]{2}$/.test(c)) return false;
if (/^0{12}/.test(c)) return false; // base zerada
return calcularDV(c.slice(0, 12)) === c.slice(12);
}
// console.log(validarCNPJ('12.ABC.345/01DE-35')); // true
// console.log(calcularDV('12ABC34501DE')); // "35"Em Node.js, é só exportar (module.exports = { validarCNPJ, calcularDV }; em CommonJS, ou export em ESM). Em TypeScript, o algoritmo é idêntico — basta anotar os tipos: normalizar(s: string): string, digito(base: string, pesos: number[]): number e validarCNPJ(cnpj: string): boolean.
Calculando os dígitos verificadores
O fluxo do DV é direto: pegue as 12 primeiras posições já normalizadas, calcule o 1º dígito com PESO1 (5,4,3,2,9,8,7,6,5,4,3,2) e, em seguida, o 2º dígito com PESO2 (6,5,4,3,2,9,8,7,6,5,4,3,2) sobre a base já com o primeiro DV anexado. A regra final é sempre a mesma: resto = soma % 11; dv = resto < 2 ? 0 : 11 - resto. Como cada caractere vira ASCII−48, as letras entram no somatório sem nenhum tratamento especial — e os dois dígitos resultantes continuam sendo números de 0 a 9.
Máscara e uso em formulário HTML
Para reexibir o número formatado depois de normalizado, aplique a máscara com um único replace:
const formatar = (c) =>
c.replace(/^(..)(...)(...)(....)(..)$/, '$1.$2.$3/$4-$5');
// formatar('12ABC34501DE35') === '12.ABC.345/01DE-35'Um exemplo mínimo de validação ao vivo, normalizando e checando a cada digitação:
<input id="cnpj" type="text" maxlength="18"
style="text-transform:uppercase" autocomplete="off">
<span id="status"></span>
<script>
const campo = document.getElementById('cnpj');
const status = document.getElementById('status');
campo.addEventListener('input', () => {
const c = normalizar(campo.value); // só A-Z e 0-9, maiúsculo
if (c.length < 14) {
status.textContent = '';
return;
}
const ok = validarCNPJ(c);
campo.value = ok ? formatar(c) : campo.value.toUpperCase();
status.textContent = ok ? '✓ válido' : '✗ inválido';
});
</script>Como testar
- Cole a função no console do navegador ou rode com
node arquivo.js. - Confira os vetores válidos abaixo: todos devem retornar
true. - Verifique que o caso de DV errado retorna
false(não basta o formato bater). - Gere massa de teste com o nosso gerador de CNPJ alfanumérico e confira no validador de CNPJ alfanumérico.
| CNPJ | Tipo | Esperado |
|---|---|---|
12.ABC.345/01DE-35 | Alfanumérico (filial) | válido |
XP.TO1.234/0001-20 | Alfanumérico (matriz) | válido |
9F.8E7.D6C/0001-36 | Alfanumérico (matriz) | válido |
A1.B2C.3D4/E5F6-68 | Alfanumérico (filial) | válido |
ZZ.ZZ0.001/AAAA-41 | Alfanumérico | válido |
2W.7H9.KQ5/R3T8-19 | Alfanumérico | válido |
11.222.333/0001-81 | Numérico clássico | válido |
12.ABC.345/01DE-34 | DV errado | inválido |
Perguntas frequentes
A mesma função valida CNPJ numérico e alfanumérico?
Sim. Como dígitos têm valor ASCII−48 igual ao próprio número, a função trata o numérico clássico como caso particular do alfanumérico. 11.222.333/0001-81 retorna true sem código separado.
Funciona em TypeScript e em frameworks como React ou Vue?
Funciona. O algoritmo é JavaScript puro, sem dependências de DOM nem de Node. Em TypeScript você só anota os tipos; em React/Vue basta importar validarCNPJ e chamá-la no handler de validação do formulário.
Por que não posso usar type="number" no input?
Porque o CNPJ alfanumérico tem letras. Campos type="number" e máscaras com \d descartam ou bloqueiam A–Z, gerando falsos inválidos. Use type="text" com text-transform: uppercase e aceite [A-Za-z0-9].
Onde encontro a versão em outras linguagens?
Temos tutoriais irmãos com o mesmo algoritmo conferido: validar CNPJ alfanumérico em PHP e validar CNPJ alfanumérico em Python.
Fontes: Receita Federal (IN RFB 2.229/2024) e nota técnica do Serpro sobre o CNPJ alfanumérico.
Ofertas em destaque
Ver todas →
Shopee
-56%
Calça Pantalona Lanzinha Feminina Cintura Alta Com Elastico De e Bolso Outono / Inverno Promoção
Amazon
-14%
Lenços Umedecidos Huggies Rosto e Corpo Limpeza 4 x 48 Un
Shopee
-60%
Brow Rise Gel Para Sobrancelhas By Ruby Rose Linha Rosa HB-E2503 Hot Sale
Amazon
-27%
Hellmann's Maionese Light 500g
Amazon
-93%
Tramontina Ducha Elétrica 3 Temperaturas 5500 W 127 V Chuveiro Branco
Mercado Livre
-20%
Malbec Pure Gold O Boticário Desodorante Colônia Perfume Masculino Original 100ml
Mercado Livre
Perfume Lattafa Bade'e Al Oud For Glory Edp Spray 100 Ml
Mercado Livre
Jaqueta Masc. Sarja Capuz Broken Rules 510075 Preto M Lisa
Mercado Livre