Validador de CNPJ Alfanumérico

Precisa de um CNPJ Alfanumérico para testar?

Ir para o Gerador de CNPJ Alfanumérico

Prepare seu Sistema para o Futuro do CNPJ

Conforme a Instrução Normativa RFB nº 2.119/2022, a Receita Federal do Brasil instituiu o novo padrão de CNPJ Alfanumérico, que poderá ser emitido a partir de julho de 2026. Esta mudança é fundamental e exige que os sistemas de software sejam adaptados com antecedência.

Implementação

JavaScript

Código JavaScript para validação do CNPJ Alfanumérico
/* cnpj.js */

class CNPJ {

  static tamanhoCNPJSemDV = 12;
  static regexCNPJSemDV = /^([A-Z\d]){12}$/;
  static regexCNPJ = /^([A-Z\d]){12}(\d){2}$/;
  static regexCaracteresMascara = /[./-]/g;
  static regexCaracteresNaoPermitidos = /[^A-Z\d./-]/i;
  static valorBase = "0".charCodeAt(0);
  static pesosDV = [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2];
  static cnpjZerado = "00000000000000";

  static isValid(cnpj) {
    if (!this.regexCaracteresNaoPermitidos.test(cnpj)) {
      let cnpjSemMascara = this.removeMascaraCNPJ(cnpj);
      if (this.regexCNPJ.test(cnpjSemMascara) && cnpjSemMascara !== this.cnpjZerado) {
        const dvInformado = cnpjSemMascara.substring(this.tamanhoCNPJSemDV);
        const dvCalculado = this.calculaDV(cnpjSemMascara.substring(0, this.tamanhoCNPJSemDV));
        return dvInformado === dvCalculado;
      }
    }
    return false;
  }

  static calculaDV(cnpj) {
    if (!this.regexCaracteresNaoPermitidos.test(cnpj)) {
      let cnpjSemMascara = this.removeMascaraCNPJ(cnpj);
      if (this.regexCNPJSemDV.test(cnpjSemMascara) && cnpjSemMascara !== this.cnpjZerado.substring(0, this.tamanhoCNPJSemDV)) {
        let somatorioDV1 = 0;
        let somatorioDV2 = 0;
        for (let i = 0; i < this.tamanhoCNPJSemDV; i++) {
          const asciiDigito = cnpjSemMascara.charCodeAt(i) - this.valorBase;
          somatorioDV1 += asciiDigito * this.pesosDV[i + 1];
          somatorioDV2 += asciiDigito * this.pesosDV[i];
        }
        const dv1 = somatorioDV1 % 11 < 2 ? 0 : 11 - (somatorioDV1 % 11);
        somatorioDV2 += dv1 * this.pesosDV[this.tamanhoCNPJSemDV];
        const dv2 = somatorioDV2 % 11 < 2 ? 0 : 11 - (somatorioDV2 % 11);
        return `${dv1}${dv2}`;
      }
    }
    throw new Error("Não é possível calcular o DV pois o CNPJ fornecido é inválido");
  }

  static removeMascaraCNPJ(cnpj) {
      return cnpj.replace(this.regexCaracteresMascara, "");
  }

}

Java

Código Java para validação do CNPJ Alfanumérico
/* CNPJValidator.java */

public class CNPJValidator {

	private static final int TAMANHO_CNPJ_SEM_DV = 12;
	private static final String REGEX_CARACTERES_FORMATACAO = "[./-]";
	private static final String REGEX_FORMACAO_BASE_CNPJ = "[A-Z\\d]{12}";
	private static final String REGEX_FORMACAO_DV = "[\\d]{2}";
	private static final String REGEX_VALOR_ZERADO = "^[0]+$";
	
	private static final int VALOR_BASE = (int) '0';
	private static final int[] PESOS_DV = { 6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2 };

	public static boolean isValid(String cnpj) {
		if (cnpj != null) {
			cnpj = removeCaracteresFormatacao(cnpj);
			if(isCnpjFormacaoValidaComDV(cnpj)) {
                String dvInformado = cnpj.substring(TAMANHO_CNPJ_SEM_DV);
                String dvCalculado = calculaDV(cnpj.substring(0, TAMANHO_CNPJ_SEM_DV));
                return dvCalculado.equals(dvInformado);
	        }
		}
		
        return false;
    }

	public static String calculaDV (String baseCnpj) {
		
		if (baseCnpj != null) {
			
			baseCnpj = removeCaracteresFormatacao(baseCnpj);
			
			  if (isCnpjFormacaoValidaSemDV(baseCnpj)) {
				  
					String dv1 = String.format("%d", calculaDigito(baseCnpj));
					String dv2 = String.format("%d", calculaDigito(baseCnpj.concat(dv1)));
					return dv1.concat(dv2);
				  
			  }
		 }
		
		throw new IllegalArgumentException(String.format("Cnpj %s não é válido para o cálculo do DV", baseCnpj));
	
	}

	private static int calculaDigito(String cnpj) {
				
		int soma = 0;
		for (int indice = cnpj.length() - 1; indice >= 0; indice--) {
			
			int valorCaracter = (int)cnpj.charAt(indice) - VALOR_BASE;
			soma += valorCaracter * PESOS_DV[PESOS_DV.length - cnpj.length() + indice];
			
		}
		return soma % 11 < 2 ? 0 : 11 - (soma % 11);
	}


	private static String removeCaracteresFormatacao(String cnpj) {
		
		return cnpj.trim().replaceAll(REGEX_CARACTERES_FORMATACAO,  "");
	}


	private static boolean isCnpjFormacaoValidaSemDV(String cnpj) {
		return cnpj.matches(REGEX_FORMACAO_BASE_CNPJ) && !cnpj.matches(REGEX_VALOR_ZERADO);
	}

	private static boolean isCnpjFormacaoValidaComDV(String cnpj) {
		return  cnpj.matches(REGEX_FORMACAO_BASE_CNPJ.concat(REGEX_FORMACAO_DV))  && !cnpj.matches(REGEX_VALOR_ZERADO);
	}
	

}
/* TesterCalculo.java */

public class TesterCalculo{

   public static void main(String[] args) {
        
        System.out.println(" ** Calculando de DV de CNPJ Alfanumerico ** ");

        if(args == null || args.length == 0) {
            System.out.println("Nenhum CNPJ informado\n");

            System.out.println("Executando testes predefinidos:");

            String [] testes = {"12ABC34501DE", 
                                "1345C3A50001",
                                "R55231B30007",
                                "90.021.382/0001", 
                                "90.024.778/0001", 
                                "90.025.108/0001", 
                                "90.025.255/0001", 
                                "90.024.420/0001"};
            String [] dvsEsperados = {"35", "06", "57", "22", "23", "21", "00", "09"};

            for(int i=0; i<testes.length; i++) {
                System.out.println( (i+1) + "   CNPJ:" + testes[i] + "    DV calculado: " + CNPJValidator.calculaDV(testes[i]) 
                    + "  DV esperado: " + dvsEsperados[i]);

            }

        }else {
            System.out.println("Calculando DV de  "+args.length+" CNPJ(s).");
            for(int i=0; i<args.length; i++) {
                System.out.println( (i+1) + "   CNPJ:" + args[i] + "    DV: " + CNPJValidator.calculaDV(args[i]));

            }
        }
    }
}
/* TesterCalculo.java */
public class TesterValidacao{

   public static void main(String[] args) {
        
        System.out.println(" ** Validando CNPJ Alfanumerico **\n ");

        if(args == null || args.length == 0) {
            System.out.println("Nenhum CNPJ informado\n");

            System.out.println("Executando testes predefinidos:");

            String [] testes = {"12ABC34501DE35",  
                                "1345C3A5000106",
                                "R55231B3000700", // dv errado
                                "1345c3A5000106", // minuscula
                                "90.021.382/0001-22", 
                                "90.024.778/000123", 
                                "90.025.108/000101", // dv errado
                                "90.025.255/0001",  // tamanho invalido
                                "90.024.420/0001A2"}; // letra no dv

            boolean [] resultadosEsperados = {true, true, false, false, true, true, false, false,false};

            for(int i=0; i<testes.length; i++) {
                System.out.println( (i+1) + "   CNPJ:" + testes[i] + "    valido? " + CNPJValidator.isValid(testes[i]) 
                    + "  resultado esperado: " + resultadosEsperados[i]);

            }

        }else {
            System.out.println("Validando  "+args.length+" CNPJ(s).");
            for(int i=0; i<args.length; i++) {
                System.out.println( (i+1) + "   CNPJ:" + args[i] + "    valido? " + CNPJValidator.isValid(args[i]));

            }
        }
    }
}

Python

Código Python para validação do CNPJ Alfanumérico
""" cnpj.py """

from dv import DigitoVerificador
import sys
import re

class CNPJ:

	def __init__(self, _input_cnpj):
		try:
			_cnpj_valido = self.__valida_formato(_input_cnpj)
			if(_cnpj_valido):
				self.cnpj = self.__remove_pontuacao(_input_cnpj)
			else:
				raise Exception("CNPJ não está no padrão aa.aaa.aaa/aaaa-dd (Para validação) ou aa.aaa.aaa/aaaa (Para geração do DV)")
		except Exception as _e:
			print(_e)
			sys.exit(0)

	
	def __remove_digitos_cnpj(self):
		if len(self.cnpj) == 14:
			self.cnpj_sem_dv = self.cnpj[0:-2]
		elif len(self.cnpj) == 12:
			self.cnpj_sem_dv = self.cnpj
		else:
			raise Exception("CNPJ com tamanho inválido!")

	def __remove_pontuacao(self, _input):
		return ''.join( x for x in _input if x not in "./-")

	def valida(self):
		self.__remove_digitos_cnpj()
		_dv = self.gera_dv()

		return "%s%s" % (self.cnpj_sem_dv, _dv) == self.cnpj

	def gera_dv(self):
		self.__remove_digitos_cnpj()
		dv1 = DigitoVerificador(self.cnpj_sem_dv)
		dv1char = '{}'.format(dv1.calcula())

		dv2 = DigitoVerificador(self.cnpj_sem_dv + dv1char)
		dv2char = '{}'.format(dv2.calcula())

		return "%s%s" % (dv1char,dv2char)

	def __valida_formato(self, _cnpj):
		return re.match(r'(^([A-Z]|\d){2}\.([A-Z]|\d){3}\.([A-Z]|\d){3}\/([A-Z]|\d){4}(\-\d{2})?$)', _cnpj)



if __name__ == "__main__":

	try:

		if len(sys.argv) < 2:
			raise Exception("Formato inválido do CNPJ.")
		_exec = sys.argv[1].upper()
		_input = sys.argv[2]

		cnpj = CNPJ(_input)
		if _exec == '-V':
			print(cnpj.valida())
		elif _exec == '-DV':
			print(cnpj.gera_dv())
		else:
			raise Exception("Opção inválida passada, as válidas são: -v para validar, -dv para gerar digito validador.")
		sys.exit()
	except Exception as _e:
		print(_e)
		sys.exit(0)
""" dv.py """

from math import ceil 
import sys

class DigitoVerificador:

 def __init__(self, _input):
 	self._cnpj = _input.upper()
 	self._pesos = list()
 	self.digito = 0
 
 def calculaAscii(self, _caracter):
  return ord(_caracter) - 48

 def calcula_soma(self):
 	_tamanho_range = len(self._cnpj)
 	_num_range = ceil(_tamanho_range / 8)
 	for i in range(_num_range):
 		self._pesos.extend(range(2,10))
 	self._pesos = self._pesos[0:_tamanho_range]
 	self._pesos.reverse()
 	sum_of_products = sum(a*b for a, b in zip(map(self.calculaAscii, self._cnpj), self._pesos))
 	return sum_of_products

 
 def calcula(self):
 
  mod_sum = self.calcula_soma() % 11
  
  if(mod_sum < 2):
  	return 0
  else:
  	return 11 - mod_sum

  return sum_of_products

if __name__ == "__main__":
	cnpj = sys.argv[1]
	dv = DigitoVerificador(cnpj)
	print(dv.calcula())

TypeScript

Código TypeScript para validação do CNPJ Alfanumérico
/* cnpj.ts */

export class CNPJ {

  private static readonly tamanhoCNPJSemDV: number = 12;
  private static readonly regexCNPJSemDV: RegExp = /^([A-Z\d]){12}$/;
  private static readonly regexCNPJ: RegExp = /^([A-Z\d]){12}(\d){2}$/;
  private static readonly regexCaracteresMascara: RegExp = /[./-]/g;
  private static readonly regexCaracteresNaoPermitidos: RegExp = /[^A-Z\d./-]/i;
  private static readonly valorBase: number = "0".charCodeAt(0);
  private static readonly pesosDV: number[] = [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2];
  private static readonly cnpjZerado: string = "00000000000000";

  static isValid(cnpj: string): boolean {
    if (!this.regexCaracteresNaoPermitidos.test(cnpj)) {
      let cnpjSemMascara = this.removeMascaraCNPJ(cnpj);
      if (this.regexCNPJ.test(cnpjSemMascara) && cnpjSemMascara !== CNPJ.cnpjZerado) {
        const dvInformado = cnpjSemMascara.substring(this.tamanhoCNPJSemDV);
        const dvCalculado = this.calculaDV(cnpjSemMascara.substring(0, this.tamanhoCNPJSemDV));
        return dvInformado === dvCalculado;
      }
    }
    return false;
  }

  static calculaDV(cnpj: string): string {
    if (!this.regexCaracteresNaoPermitidos.test(cnpj)) {
      let cnpjSemMascara = this.removeMascaraCNPJ(cnpj);
      if (this.regexCNPJSemDV.test(cnpjSemMascara) && cnpjSemMascara !== this.cnpjZerado.substring(0, this.tamanhoCNPJSemDV)) {
        let somatorioDV1 = 0;
        let somatorioDV2 = 0;
        for (let i = 0; i < this.tamanhoCNPJSemDV; i++) {
          const asciiDigito = cnpjSemMascara.charCodeAt(i) - this.valorBase;
          somatorioDV1 += asciiDigito * this.pesosDV[i + 1];
          somatorioDV2 += asciiDigito * this.pesosDV[i];
        }
        const dv1 = somatorioDV1 % 11 < 2 ? 0 : 11 - (somatorioDV1 % 11);
        somatorioDV2 += dv1 * this.pesosDV[this.tamanhoCNPJSemDV];
        const dv2 = somatorioDV2 % 11 < 2 ? 0 : 11 - (somatorioDV2 % 11);
        return `${dv1}${dv2}`;
      }
    }
    throw new Error("Não é possível calcular o DV pois o CNPJ fornecido é inválido");
  }

  private static removeMascaraCNPJ(cnpj: string): string {
      return cnpj.replace(this.regexCaracteresMascara, "");
  }

}
/* calculo.ts */

import { CNPJ } from "./cnpj";
import process from 'node:process';

if (process.argv.length > 2) {
    for (let i = 2, j = 1; i < process.argv.length; i++, j++) {
        const cnpj = process.argv[i];
        try {
            const dvCalculado: string = CNPJ.calculaDV(cnpj);
            console.info(`[${j}] CNPJ: [${cnpj}] DV: [${dvCalculado}]`);
        } catch (e) {
            console.error(`[${j}] Ocorreu um erro ao calcular o DV do CNPJ [${cnpj}].`);
            console.error(e);
        }
    }
} else {
    console.error("Não foi passado nenhuma argumento.");
}
/* test.ts */

import { CNPJ } from "./cnpj";

try {

    assertEquals("91", CNPJ.calculaDV("000000000001"));
    assertEquals("35", CNPJ.calculaDV("12.ABC.345/01DE"));

    assertThrows(Error, () => CNPJ.calculaDV("")); //Vazio
    assertThrows(Error, () => CNPJ.calculaDV("'!@#$%&*-_=+^~")); //Apenas caracteres não permitido
    assertThrows(Error, () => CNPJ.calculaDV("$0123456789A")); //Caracter não permitido no início
    assertThrows(Error, () => CNPJ.calculaDV("012345?6789A")); //Caracter não permitido no meio
    assertThrows(Error, () => CNPJ.calculaDV("0123456789A#")); //Caracter não permitido no final
    assertThrows(Error, () => CNPJ.calculaDV("12ABc34501DE")); //Com letra minúscula
    assertThrows(Error, () => CNPJ.calculaDV("00000000000")); //Dígitos a menos
    assertThrows(Error, () => CNPJ.calculaDV("00000000000191")); //Dígitos a mais

    assertTrue(CNPJ.isValid("12.ABC.345/01DE-35"));
    assertTrue(CNPJ.isValid("90.021.382/0001-22"));
    assertTrue(CNPJ.isValid("90.024.778/0001-23"));
    assertTrue(CNPJ.isValid("90.025.108/0001-21"));
    assertTrue(CNPJ.isValid("90.025.255/0001-00"));
    assertTrue(CNPJ.isValid("90.024.420/0001-09"));
    assertTrue(CNPJ.isValid("90.024.781/0001-47"));
    assertTrue(CNPJ.isValid("04.740.714/0001-97"));
    assertTrue(CNPJ.isValid("44.108.058/0001-29"));
    assertTrue(CNPJ.isValid("90.024.780/0001-00"));
    assertTrue(CNPJ.isValid("90.024.779/0001-78"));
    assertTrue(CNPJ.isValid("00000000000191"));
    assertTrue(CNPJ.isValid("ABCDEFGHIJKL80"));
    
    assertFalse(CNPJ.isValid("")); //Vazio
    assertFalse(CNPJ.isValid("'!@#$%&*-_=+^~")); //Apenas caracteres não permitido
    assertFalse(CNPJ.isValid("$0123456789ABC")); //Caracter não permitido no início
    assertFalse(CNPJ.isValid("0123456?789ABC")); //Caracter não permitido no meio
    assertFalse(CNPJ.isValid("0123456789ABC#")); //Caracter não permitido no fim
    assertFalse(CNPJ.isValid("12.ABc.345/01DE-35")); //Com letra minúscula
    assertFalse(CNPJ.isValid("0000000000019")); //Dígitos a menos
    assertFalse(CNPJ.isValid("000000000001911")); //Dígitos a mais
    assertFalse(CNPJ.isValid("0000000000019L")); //Letra na posição do segundo DV
    assertFalse(CNPJ.isValid("000000000001P1")); //Letra na posição do primeiro DV
    assertFalse(CNPJ.isValid("00000000000192")); //DV inválido
    assertFalse(CNPJ.isValid("ABCDEFGHIJKL81")); //DV inválido
    assertFalse(CNPJ.isValid("00000000000000")); //CNPJ zerado
    assertFalse(CNPJ.isValid("00.000.000/0000-00")); //CNPJ zerado com máscara

    console.info("All tests passed successfully!");
    
} catch (e: unknown) {
    console.error("Some of the tests failed.");
    if (e instanceof Error) {
        console.error(e.message, e.stack);
    } else {
        console.error(e);
    }
}

function assertTrue(value: any) {
    assertEquals(true, value);
}

function assertFalse(value: any) {
    assertEquals(false, value);
}

function assertEquals(expected: any, actual: any) {
    if (expected !== actual) {
        const message = `Assertion error: expected [${expected}] but was [${actual}].`;
        throw new Error(message);
    }
}

function assertThrows(expectedType: any, executable: Function) {
    try {
        executable();
    } catch(e: unknown) {
        if (e instanceof expectedType) {
            return;
        }
        const message = `Assertion error: expected instance of [${expectedType}] to be thrown but it was [${e}].`;
        throw new Error(message);
    }
    const message = `Assertion error: expected [${expectedType}] to be thrown but nothing was thrown.`;
    throw new Error(message);
}
/* validacao.ts */

import { CNPJ } from "./cnpj";
import process from 'node:process';

if (process.argv.length > 2) {
    for (let i = 2, j = 1; i < process.argv.length; i++, j++) {
        const cnpj = process.argv[i];
        const isValid: boolean = CNPJ.isValid(cnpj);
        console.info(`[${j}] O CNPJ [${cnpj}] ${ isValid ? 'é válido' : 'não é válido' }.`);
    }
} else {
    console.error("Não foi passado nenhuma argumento.");
}

Perguntas Frequentes (FAQ)

É o novo padrão oficial para o Cadastro Nacional da Pessoa Jurídica, instituído pela Instrução Normativa RFB nº 2.119 de 2022. A partir de julho de 2026, a Receita Federal poderá emitir novos CNPJs contendo letras e números, expandindo as possibilidades de combinações.

A mudança impacta diretamente todos os sistemas que armazenam ou validam CNPJs. É crucial que os desenvolvedores preparem suas aplicações com antecedência, ajustando bancos de dados (ex: de campos numéricos para alfanuméricos/varchar), validações de front-end, máscaras e integrações de API. Esperar até 2026 para adaptar os sistemas pode gerar custos e problemas significativos.

Sim. Nossa ferramenta valida CNPJs que seguem as especificações e exemplos divulgados pela Receita Federal para o novo padrão. Ela serve como uma forma precisa para você testar a compatibilidade e a robustez do seu software.

Não. Os CNPJs numéricos já existentes continuarão válidos e ativos. A mudança se aplica à geração de novos números a partir da data estipulada. Portanto, os sistemas precisarão ser capazes de lidar com ambos os formatos: o numérico tradicional e o novo alfanumérico.