A regra em uma frase
valor do caractere = código ASCII − 48 · pesos 2 a 9 da direita para a esquerda · soma ÷ 11 · resto < 2 → dígito 0, senão dígito = 11 − resto
Passo 1 — converter cada caractere em número
Antes de qualquer multiplicação, cada posição do CNPJ vira um número. A conversão é o código do caractere na tabela ASCII menos 48:
| Grupo | Valores usados no cálculo |
|---|---|
| Dígitos | 0 = 0 · 1 = 1 · 2 = 2 · 3 = 3 · 4 = 4 · 5 = 5 · 6 = 6 · 7 = 7 · 8 = 8 · 9 = 9 |
| Letras | A = 17 · B = 18 · C = 19 · D = 20 · E = 21 · F = 22 · G = 23 · H = 24 · I = 25 · J = 26 · K = 27 · L = 28 · M = 29 · N = 30 · O = 31 · P = 32 · Q = 33 · R = 34 · S = 35 · T = 36 · U = 37 · V = 38 · W = 39 · X = 40 · Y = 41 · Z = 42 |
É essa escolha que garante a compatibilidade total com o formato antigo: como 0 vale 0 e 9 vale 9, um CNPJ puramente numérico produz exatamente o mesmo resultado no algoritmo novo e no antigo.
Passo 2 — aplicar os pesos
Os pesos vão de 2 a 9, contados da direita para a esquerda, e recomeçam em 2 depois do 9. Para os 12 caracteres da base, lidos da esquerda para a direita, a sequência fica:
5 · 4 · 3 · 2 · 9 · 8 · 7 · 6 · 5 · 4 · 3 · 2
E para os 13 caracteres do segundo dígito:
6 · 5 · 4 · 3 · 2 · 9 · 8 · 7 · 6 · 5 · 4 · 3 · 2
Uma forma prática de escrever isso em código, sem tabela fixa, é peso = ((tamanho - 1 - índice) % 8) + 2 — funciona para os dois tamanhos.
Passo 3 — somar, dividir por 11 e achar o dígito
- Separe a base dos dígitos verificadores. Em
12.ABC.345/01DE-35, a base são os 12 primeiros caracteres:12ABC34501DE. Os dois últimos (35) são o que vamos recalcular. - Converta cada caractere em número. O valor é o código ASCII do caractere menos 48. Números viram eles mesmos (
0→0,9→9) e letras começam em 17 (A→17,B→18, atéZ→42). - Multiplique pelos pesos. Da direita para a esquerda, os pesos são 2, 3, 4, 5, 6, 7, 8, 9 e recomeçam em 2.
- Some tudo e divida por 11. Se o resto for 0 ou 1, o dígito é 0. Caso contrário, o dígito é 11 menos o resto.
- Repita para o segundo dígito, agora com 13 caracteres: a base mais o primeiro dígito que você acabou de calcular.
1º dígito verificador — base 12ABC34501DE
| Caractere | Valor (ASCII − 48) | Peso | Produto |
|---|---|---|---|
1 | 1 | 5 | 5 |
2 | 2 | 4 | 8 |
A | 17 | 3 | 51 |
B | 18 | 2 | 36 |
C | 19 | 9 | 171 |
3 | 3 | 8 | 24 |
4 | 4 | 7 | 28 |
5 | 5 | 6 | 30 |
0 | 0 | 5 | 0 |
1 | 1 | 4 | 4 |
D | 20 | 3 | 60 |
E | 21 | 2 | 42 |
| Soma | 459 |
459 ÷ 11 deixa resto 8. Como o resto é 2 ou maior, o dígito é 11 − 8 = 3.
2º dígito verificador — base + 3 = 12ABC34501DE3
| Caractere | Valor (ASCII − 48) | Peso | Produto |
|---|---|---|---|
1 | 1 | 6 | 6 |
2 | 2 | 5 | 10 |
A | 17 | 4 | 68 |
B | 18 | 3 | 54 |
C | 19 | 2 | 38 |
3 | 3 | 9 | 27 |
4 | 4 | 8 | 32 |
5 | 5 | 7 | 35 |
0 | 0 | 6 | 0 |
1 | 1 | 5 | 5 |
D | 20 | 4 | 80 |
E | 21 | 3 | 63 |
3 | 3 | 2 | 6 |
| Soma | 424 |
424 ÷ 11 deixa resto 6. Como o resto é 2 ou maior, o dígito é 11 − 6 = 5.
Juntando os dois: o dígito verificador de 12ABC34501DE é 35, ou seja, o CNPJ completo é 12.ABC.345/01DE-35 — exatamente o exemplo divulgado pela Receita Federal.
Conferindo com o CNPJ numérico antigo
Vale repetir a conta com um CNPJ tradicional para ver que nada mudou. Tomando a base 112223330001:
1×5 + 1×4 + 2×3 + 2×2 + 2×9 + 3×8 + 3×7 + 3×6 + 0×5 + 0×4 + 0×3 + 1×2 = 123 123 ÷ 11 → resto 2 → dígito = 11 − 2 = 8
Repetindo para os 13 caracteres 1122233300018 chega-se ao segundo dígito 1, formando 11.222.333/0001-81 — o CNPJ de exemplo mais conhecido do país, validado pelo algoritmo novo sem nenhuma adaptação.
Implementações
O trecho abaixo é a tradução literal dos três passos. A mesma função existe nesta página em 10 linguagens.
function digito(sequencia) {
let soma = 0;
for (let i = 0; i < sequencia.length; i += 1) {
const valor = sequencia.charCodeAt(i) - 48;
const peso = ((sequencia.length - 1 - i) % 8) + 2;
soma += valor * peso;
}
const resto = soma % 11;
return resto < 2 ? 0 : 11 - resto;
}
function calcularDv(base) {
const primeiro = digito(base); // sobre 12 caracteres
const segundo = digito(`${base}${primeiro}`); // sobre 13 caracteres
return `${primeiro}${segundo}`;
}
calcularDv('12ABC34501DE'); // '35'
calcularDv('112223330001'); // '81'