---
title: "Validar CNPJ numérico e alfanumérico no cadastro"
description: "Função em JavaScript, sem dependências, que normaliza e valida o CNPJ numérico e o alfanumérico (letras nas 12 primeiras posições) pelo dígito verificador, antes de chamar a API."
canonical: "https://cnpj.ia.br/exemplos/validar-cnpj-alfanumerico"
date_modified: 2026-09-23
source: "cnpj.ia.br"
---

Exemplo

# Validar CNPJ numérico e alfanumérico no cadastro

Função em JavaScript, sem dependências, que normaliza e valida o CNPJ numérico e o alfanumérico (letras nas 12 primeiras posições) pelo dígito verificador, antes de chamar a API.

JavaScript Node.js [Código no GitHub](https://github.com/Atmosphere-Technologies/cnpj-ia-exemplos/blob/main/node/validar-cnpj.mjs)

`validarCnpj()` devolve `{ valido, cnpj }` para os dois formatos de CNPJ, o numérico e o alfanumérico que a Receita Federal emite desde 2026, e diz o motivo quando recusa: `formato`, `repetido` ou `digito`. Roda no formulário, antes de qualquer chamada, e não tem dependência.

## O problema

Validação de CNPJ escrita para 14 dígitos recusa o CNPJ alfanumérico, que tem letras nas 12 primeiras posições; máscara de entrada com `##.###.###/####-##` também. Ao mesmo tempo, mandar para a API tudo o que o usuário digitou gasta uma chamada por erro de digitação.

## O fluxo

1. Normaliza: tira espaços nas pontas, passa para maiúsculas e remove pontos, barra e hífen. É a forma que a API devolve em `data.cnpj`.
2. Confere o formato: 12 caracteres entre letras maiúsculas e dígitos, mais 2 dígitos verificadores numéricos.
3. Recusa os 14 caracteres iguais, que passam no cálculo mas não são CNPJ.
4. Calcula os dois dígitos: cada caractere vale o código ASCII menos 48 (dígitos de 0 a 9, letras de 17 a 42), módulo 11 com pesos de 2 a 9 da direita para a esquerda; resto menor que 2 dá 0, senão 11 menos o resto. Só com dígitos, é o cálculo de sempre.

A API valida de novo: formato ou dígito inválido responde `400 invalid_cnpj`, e CNPJ válido que não existe responde `404 not_found`, os dois sem custo. Mais em [CNPJ alfanumérico](https://cnpj.ia.br/docs/cnpj-alfanumerico) e [Dígito verificador do CNPJ](https://cnpj.ia.br/glossario/digito-verificador-cnpj).

## O código

```js
// Validação de CNPJ no cadastro, antes de chamar a API: numérico e alfanumérico.
//
//   node validar-cnpj.mjs 12.ABC.345/01DE-35
//
// Desde 2026 a Receita emite CNPJ alfanumérico: as 12 primeiras posições
// aceitam letras maiúsculas e dígitos, os 2 dígitos verificadores continuam
// numéricos. Cada caractere vale (código ASCII - 48): dígitos valem 0 a 9,
// letras de 17 (A) a 42 (Z). Módulo 11 com pesos 2 a 9 da direita para a
// esquerda; resto menor que 2 dá 0, senão 11 - resto. Para CNPJ só com
// dígitos, é o cálculo de sempre.
//
// Validar aqui evita uma chamada por erro de digitação. A API valida de novo e
// responde 400 invalid_cnpj, sem custo; CNPJ válido que não existe responde
// 404 not_found.

import { pathToFileURL } from "node:url";

const PESOS = [2, 3, 4, 5, 6, 7, 8, 9];

// Maiúsculas, sem pontuação e sem espaços: a forma que a API devolve em data.cnpj.
export function normalizarCnpj(valor) {
  return String(valor).trim().toUpperCase().replace(/[./-]/g, "");
}

function digito(base) {
  let soma = 0;
  for (let i = 0; i < base.length; i++) {
    soma += (base.charCodeAt(base.length - 1 - i) - 48) * PESOS[i % 8];
  }
  const resto = soma % 11;
  return resto < 2 ? 0 : 11 - resto;
}

// { valido, cnpj } ou { valido: false, cnpj, motivo: "formato" | "repetido" | "digito" }
export function validarCnpj(valor) {
  const cnpj = normalizarCnpj(valor);
  if (!/^[A-Z0-9]{12}[0-9]{2}$/.test(cnpj)) return { valido: false, cnpj, motivo: "formato" };
  if (/^(.)\1{13}$/.test(cnpj)) return { valido: false, cnpj, motivo: "repetido" };
  const d1 = digito(cnpj.slice(0, 12));
  const d2 = digito(cnpj.slice(0, 12) + d1);
  if (cnpj.slice(12) !== `${d1}${d2}`) return { valido: false, cnpj, motivo: "digito" };
  return { valido: true, cnpj };
}

if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
  const entrada = process.argv[2];
  if (!entrada) {
    console.error("Uso: node validar-cnpj.mjs <CNPJ>");
    process.exit(2);
  }
  const resultado = validarCnpj(entrada);
  console.log(JSON.stringify(resultado));
  process.exit(resultado.valido ? 0 : 1);
}
```

```js
import { validarCnpj } from "./validar-cnpj.mjs";

validarCnpj("12.ABC.345/01DE-35"); // { valido: true, cnpj: "12ABC34501DE35" }
validarCnpj("00000000000192");     // { valido: false, cnpj: "00000000000192", motivo: "digito" }
```

Os testes, com os vetores numérico, alfanumérico, dígito errado, repetição e formato, estão em [`node/validar-cnpj.test.mjs`](https://github.com/Atmosphere-Technologies/cnpj-ia-exemplos/blob/main/node/validar-cnpj.test.mjs) e rodam com `node --test`. A validação não chama a API e não consome créditos.
