A Receita federal publicou uma mudança que vai afetar a maneira como os números de CNPJ são criados. Atualmente, as empresas no Brasil são registradas e identificadas por um número de 14 dígitos composto apenas por números. A partir de 2026, no entanto, o registro passará a ser realizados com letras e números.
Quem trabalha com desenvolvimento de sistemas, especialmente na criação de API, CRUDs de qualquer espécie, sobretudo para contextos corporativos, já deve ter se deparado com a necessidade de validar se um número de CNPJ está correto. Para isso, existe uma regra aplicada sobre cada dígito do CNPJ que resultam nos últimos 2 dígitos. Em outras palavras, os últimos 2 dígitos do CNPJ são formados por uma combinação dos dígitos anteriores.
Para o novo formato de CNPJ, felizmente, a regra de validação não vai mudar e, para as letras, serão atribuídos valores numéricos. Com isso, as rotinas existentes preseciam ser ajustadas para converter caracteres em seus respectivos valores números.
Esses valores numéricos são baseados no valor de cada dígito da tabela ASCII, incluindo os dígitos númericos, conforme imagem abaixo. Para as letras, são consideradas apenas suas versões em maiúsculas. Dos valores ASCII de cada caractere alfanumérico é subitraído o valro 48 e, dessa forma, os catecteres numéricos continuarão com o valor que eles representam, como 0=0, 1=1, 2=2… Para as letas, teremos A=17, B=18… após a subtração do valor 48 de seu valor ASCII.
O dígito verificador do CNPJ continua sendo um valor formado exclusivamente por números.
Validação
A validação do CNPJ é uma regra bem definida. Mas a origem da infomação que vai ser validade pode dependenr de cada sistema. Pode-se usar um valor string com mácara, isto é, os pontos de /, uma outra alternativa é usar um valor string sem a máscara. Há quem prefira armazenar o CNPJ como um valor inteiro e só converter em string (com ou sem máscara) apenas na hora de mostrar a informação para o usuário; essa opção não será mais possível com o novo modelo de CNPJ. As possibilidades são muitas.
Independente de como o CNPJ está armazenado dentro de um sistema, na hora da validação, cada um de seus dígitos precisam ser considerados como valores numéricos.
A validação de um CNPJ multiplica cada caractere por um valor pré estabelecido, baseado na posição desse caractere dentro do CNPJ. Dessa operação matemática obtemos o primeiro dígito verificador. Então o processo é repetido com adição do primeiro dígito verificador ao valor original. Isso resulta no segundo dígito verificador. Se os dois dígitos encontrados forem iguais ao do CNPJ sendo validado, ele é válido.
Vamos considerar o CNPJ 19.JA2.KO8/Z001-51, onde 51 é o dígito verificador. Dessa forma, precisamos aplicar o algoritmo em cima do valor 19.JA2.KO8/P001 e verificar os dígitos obitidos são iguais a XX.
A primeira etapa é multiplicar cada dígito do CNPJ pelo seu multiplicador conforme a tabela abaixo. A primeira linha são os dígitos do CNPJ, enquanto a linha de baixo são os multiplicadoress; eles são fixos e aplicados para qualquer CNPJ. A terceira linha é o resultado da multiplicação da primeira e segunda linha.
1 | 9 | J=26 | A=17 | 2 | K=27 | O=31 | 8 | Z=42 | 0 | 0 | 1 |
5 | 4 | 3 | 2 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 |
5 | 36 | 78 | 34 | 18 | 216 | 217 | 48 | 210 | 0 | 0 | 2 |
O valor de cada multiplicação devem ser somados e o resultado deve ser aplicada uma divisão inteira, cujo valor de interesse é o resto da divisão. Assim (5+36+78+34+18+216+217+48+210+0+0+1) = 864, com 864 % 11 = 6. Agora, se o resto for 0 ou 1, então o primeiro dígito verificador deve ser igual a 0, cao contrário, subtraímos o resto de 11 e o resultado será o dígitivo verificador. No nosso exemplo, o resto da divisão é 6, portanto, 11-6 = 5, que é o nosso primeiro dígito verificador.
Para encontrar o segundo dígito verificador, adicionado o primeiro dígito ao final do CNPJ sendo validado e repetimos o mesmo processo usando a tabela de multiplicadores abaixo.
1 | 9 | J=26 | A=17 | 2 | K=27 | O=31 | 8 | Z=42 | 0 | 0 | 1 | DV1 = 5 |
6 | 5 | 4 | 3 | 2 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 |
6 | 45 | 104 | 51 | 4 | 243 | 248 | 56 | 252 | 0 | 0 | 3 | 10 |
Somamos os restauldos, e assim (6+45+104+51+4+243+248+56+252+0+0+3+10) = 1022, com 1022 % 11 = 10. Sobre o resto 10, como ele maior que 1, subtraímos ele de 11, logo 11-10 = 1, com 1 sendo nosso segundo dígito verificador.
Os valores encontrados foram 5 e 1. Logo, o CNPJ do exemplo é válido, pois os valores encontrados são os mesmos do registro.
O código a seguir é uma exemplo em Java implementando uma validação do novo CNPJ. A rotina que realiza a validação espera que o CNPJ esteja completo e com máscara.
import java.util.regex.Pattern;
import javax.swing.text.MaskFormatter;
public class ValidacaoNovoCnpj {
private static final Pattern pattern = Pattern.compile("[0-9A-Z]{2}\\.[0-9A-Z]{3}\\.[0-9A-Z]{3}/[0-9A-Z]{4}-[0-9]{2}");
private static final int multiplicadores[] = {
6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2
};
public static int multiplicarSomarDividir(String cnpj, int length, int shift) {
var soma = 0;
for(int i = 0; i < length; i++) {
soma += (cnpj.charAt(i) - 48) * multiplicadores[i + shift];
}
return soma % 11;
}
public static boolean isCnpjValido(String cnpj) {
if(cnpj == null || !pattern.matcher(cnpj).matches()) return false;
var cnpjSemMascara = cnpj.replaceAll("[\\./-]", "");
cnpjSemMascara = cnpjSemMascara.substring(0, cnpjSemMascara.length() - 2);
var soma1 = multiplicarSomarDividir(cnpjSemMascara, 12, 1);
var dv1 = soma1 < 2 ? 0 : 11 - soma1;
cnpjSemMascara = cnpjSemMascara + dv1;
var soma2 = multiplicarSomarDividir(cnpjSemMascara, 13, 0);
var dv2 = soma2 < 2 ? 0 : 11 - soma2;
return dv1 == (cnpj.charAt(cnpj.length() - 2) - '0')
&& dv2 == (cnpj.charAt(cnpj.length() - 1) - '0');
}
public static void main(String [] args) {
// teste 1 - CNPJ válido
var cnpjExemplo1 = "19.JA2.KO8/Z001-51";
var cnpjValido1 = isCnpjValido(cnpjExemplo1);
System.out.println(String.format(
"CNPJ %s é válido? %s",
cnpjExemplo1,
cnpjValido1 ? "sim" : "não"
));
// teste 2 - CNPJ válido com máscara inválida
var cnpjExemplo2 = "19JA2KO8Z00199";
var cnpjValido2 = isCnpjValido(cnpjExemplo2);
System.out.println(String.format(
"CNPJ %s é válido? %s",
cnpjExemplo2,
cnpjValido2 ? "sim" : "não"
));
// teste 2 - CNPJ com DV inválido
var cnpjExemplo3 = "3A.JU2.KX8/Z001-81";
var cnpjValido3 = isCnpjValido(cnpjExemplo3);
System.out.println(String.format(
"CNPJ %s é válido? %s",
cnpjExemplo3,
cnpjValido3 ? "sim" : "não"
));
}
}
Referências
19/06/2024 | Reforma Tributária – Nota Técnica nº 49/2024, COCAD/SUARA/RFB – Novo formato de CNPJ em alfanumérico – https://documentacao.senior.com.br/exigenciaslegais/materias/erp/2024/2024-06-19-nota-tecnica-n49-2024-cocad-suara-rfb-novo-formato-de-cnpj-em-alfanumerico.htm
Algoritmo para Validação do CNPJ – https://www.macoratti.net/alg_cnpj.htm