Validador de CNH
Digite o número de registro da carteira de habilitação e veja na hora se os dois dígitos verificadores conferem.
Processamento local: nada do que você digita sai do seu navegador.
Como usar
Digite o número de registro da CNH (11 dígitos; não confunda com o número do espelho ou o código de segurança). O resultado aparece enquanto você digita e indica qual dígito verificador não confere.
Como os dígitos são calculados
O 1º dígito usa os 9 primeiros dígitos com pesos de 9 a 1; se o resto da divisão por 11 for 10 ou mais, vira 0 e guarda-se um desconto de 2. O 2º dígito usa os mesmos 9 dígitos com pesos de 1 a 9; do resto subtrai-se o desconto (somando 11 se ficar negativo) e, se der 10 ou mais, vira 0.
Essa é a rotina difundida entre os validadores de CNH, usada há muitos anos. Ela garante apenas a consistência do número; não consulta o Renach/Senatran e não diz se a habilitação existe ou está vigente.
Como implementar em código
Exemplos prontos para usar no seu projeto.
// CNH: 11 dígitos; os 2 últimos são DVs (módulo 11)
function cnhValida(valor) {
const n = String(valor).replace(/\D/g, '');
if (n.length !== 11 || /^(\d)\1{10}$/.test(n)) return false;
const d = n.split('').map(Number);
let v = 0, dsc = 0;
for (let i = 0; i < 9; i++) v += d[i] * (9 - i); // pesos 9..1
let dv1 = v % 11;
if (dv1 >= 10) { dv1 = 0; dsc = 2; } // guarda o desconto para o 2º DV
v = 0;
for (let i = 0; i < 9; i++) v += d[i] * (i + 1); // pesos 1..9
let dv2 = (v % 11) - dsc;
if (dv2 < 0) dv2 += 11;
if (dv2 >= 10) dv2 = 0;
return dv1 === d[9] && dv2 === d[10];
}
console.log(cnhValida('02650306461')); // trueimport re
def cnh_valida(valor: str) -> bool:
"""CNH: 11 dígitos; os 2 últimos são DVs (módulo 11)."""
n = re.sub(r"\D", "", valor)
if len(n) != 11 or len(set(n)) == 1:
return False
d = [int(c) for c in n]
dsc = 0
v = sum(d[i] * (9 - i) for i in range(9)) # pesos 9..1
dv1 = v % 11
if dv1 >= 10:
dv1, dsc = 0, 2 # guarda o desconto para o 2º DV
v = sum(d[i] * (i + 1) for i in range(9)) # pesos 1..9
dv2 = v % 11 - dsc
if dv2 < 0:
dv2 += 11
if dv2 >= 10:
dv2 = 0
return dv1 == d[9] and dv2 == d[10]
print(cnh_valida("02650306461")) # Trueimport "regexp"
var naoDigito = regexp.MustCompile(`\D`)
// CnhValida valida o número de registro da CNH (11 dígitos, 2 DVs).
func CnhValida(valor string) bool {
n := naoDigito.ReplaceAllString(valor, "")
if len(n) != 11 {
return false
}
d := make([]int, 11)
repetido := true
for i := range d {
d[i] = int(n[i] - '0')
if n[i] != n[0] {
repetido = false
}
}
if repetido {
return false
}
v, dsc := 0, 0
for i := 0; i < 9; i++ {
v += d[i] * (9 - i) // pesos 9..1
}
dv1 := v % 11
if dv1 >= 10 {
dv1, dsc = 0, 2 // guarda o desconto para o 2º DV
}
v = 0
for i := 0; i < 9; i++ {
v += d[i] * (i + 1) // pesos 1..9
}
dv2 := v%11 - dsc
if dv2 < 0 {
dv2 += 11
}
if dv2 >= 10 {
dv2 = 0
}
return dv1 == d[9] && dv2 == d[10]
}/// CNH: 11 dígitos; os 2 últimos são DVs (módulo 11).
bool cnhValida(String valor) {
final n = valor.replaceAll(RegExp(r'\D'), '');
if (n.length != 11 || RegExp(r'^(\d)\1{10}$').hasMatch(n)) return false;
final d = n.split('').map(int.parse).toList();
var v = 0, dsc = 0;
for (var i = 0; i < 9; i++) {
v += d[i] * (9 - i); // pesos 9..1
}
var dv1 = v % 11;
if (dv1 >= 10) {
dv1 = 0;
dsc = 2; // guarda o desconto para o 2º DV
}
v = 0;
for (var i = 0; i < 9; i++) {
v += d[i] * (i + 1); // pesos 1..9
}
var dv2 = v % 11 - dsc;
if (dv2 < 0) dv2 += 11;
if (dv2 >= 10) dv2 = 0;
return dv1 == d[9] && dv2 == d[10];
}final class Validador {
/** CNH: 11 dígitos; os 2 últimos são DVs (módulo 11). */
static boolean cnhValida(String valor) {
String n = valor.replaceAll("\\D", "");
if (n.length() != 11 || n.matches("(\\d)\\1{10}")) return false;
int[] d = new int[11];
for (int i = 0; i < 11; i++) d[i] = n.charAt(i) - '0';
int v = 0, dsc = 0;
for (int i = 0; i < 9; i++) v += d[i] * (9 - i); // pesos 9..1
int dv1 = v % 11;
if (dv1 >= 10) { dv1 = 0; dsc = 2; } // guarda o desconto para o 2º DV
v = 0;
for (int i = 0; i < 9; i++) v += d[i] * (i + 1); // pesos 1..9
int dv2 = v % 11 - dsc;
if (dv2 < 0) dv2 += 11;
if (dv2 >= 10) dv2 = 0;
return dv1 == d[9] && dv2 == d[10];
}
}<?php
// CNH: 11 dígitos; os 2 últimos são DVs (módulo 11)
function cnhValida(string $valor): bool {
$n = preg_replace('/\D/', '', $valor);
if (strlen($n) !== 11 || preg_match('/^(\d)\1{10}$/', $n)) return false;
$d = array_map('intval', str_split($n));
$v = 0; $dsc = 0;
for ($i = 0; $i < 9; $i++) $v += $d[$i] * (9 - $i); // pesos 9..1
$dv1 = $v % 11;
if ($dv1 >= 10) { $dv1 = 0; $dsc = 2; } // guarda o desconto para o 2º DV
$v = 0;
for ($i = 0; $i < 9; $i++) $v += $d[$i] * ($i + 1); // pesos 1..9
$dv2 = $v % 11 - $dsc;
if ($dv2 < 0) $dv2 += 11;
if ($dv2 >= 10) $dv2 = 0;
return $dv1 === $d[9] && $dv2 === $d[10];
}using System.Linq;
using System.Text.RegularExpressions;
public static class Validador
{
// CNH: 11 dígitos; os 2 últimos são DVs (módulo 11)
public static bool CnhValida(string valor)
{
var n = Regex.Replace(valor, @"\D", "");
if (n.Length != 11 || n.Distinct().Count() == 1) return false;
var d = n.Select(c => c - '0').ToArray();
int v = 0, dsc = 0;
for (int i = 0; i < 9; i++) v += d[i] * (9 - i); // pesos 9..1
int dv1 = v % 11;
if (dv1 >= 10) { dv1 = 0; dsc = 2; } // guarda o desconto para o 2º DV
v = 0;
for (int i = 0; i < 9; i++) v += d[i] * (i + 1); // pesos 1..9
int dv2 = v % 11 - dsc;
if (dv2 < 0) dv2 += 11;
if (dv2 >= 10) dv2 = 0;
return dv1 == d[9] && dv2 == d[10];
}
}Perguntas frequentes
Qual número da CNH deve ser validado?
O número de registro, de 11 dígitos. O número do espelho e o código de segurança têm outra formação e não são validados aqui.
A validação diz se a CNH está válida para dirigir?
Não. Ela só confere os dígitos verificadores. A situação da habilitação só pode ser consultada nos canais oficiais de trânsito.
Veja também
Precisa de um sistema ou app sob medida?
A VcInova desenvolve software, aplicativos e integrações para empresas de todo o Brasil.
Fale com a VcInova