-
-
Save cagartner/efe5e37c9c52063660cd to your computer and use it in GitHub Desktop.
O algoritmo para validação de Renavam é um algoritmo módulo 11 e, atualmente, possui 11 dígitos. A lógica pra validar um renavam deve ser usado o módulo 11 explicado aqui:
https://pt.wikipedia.org/wiki/D%C3%ADgito_verificador
Um exemplo em Java pode ser encontrado aqui:
https://victorjabur.com/2010/05/28/renavam_veiculos_java/
Um exemplo em Python que escrevi aqui pra usar em um projeto django:
import re def get_factor(num): digits = [2, 3, 4, 5, 6, 7, 8, 9] if num >= len(digits): index = num % len(digits) else: index = num return digits[index] def get_digito_verificador(renavam): return int(renavam[-1]) def get_digitos_invertidos(renavam): renavam = str(renavam)[0:(len(renavam) -1)] digitos = [] for char in renavam: digitos += [int(char)] digitos.reverse() return digitos def get_soma(digitos): soma = 0 for i in range(0, len(digitos)): soma += digitos[i] * get_factor(i) return soma def get_verificador(soma): valor = 11 - (soma % 11) if valor >= 10: return 0 return valor def validate_renavam(renavam): if len(renavam) != 11: renavam = str(renavam).ljust(11, '0') if not re.match('^\d{11}$', renavam): return False digitos = get_digitos_invertidos(renavam) verificador = get_digito_verificador(renavam) soma = get_soma(digitos) verificador_calculado = get_verificador(soma) return verificador_calculado == verificador print(validate_renavam('54088307874'))o número 54088307874 vem do https://www.4devs.com.br/gerador_de_renavam
Acrescentando uma pequena correção: na segunda linha da função validate_renavam, ljust serve para adicionar caracteres do lado direito da string, então o correto é usar o rjust para adicionar os 0s à esquerda:
def validate_renavam(renavam):
if len(renavam) != 11:
renavam = str(renavam).rjust(11, '0')
Acrescentando uma pequena correção: na segunda linha da função validate_renavam. ljust serve para adicionar caracteres do lado direito da string, então o correto é usar o rjust para adicionar os 0s à esquerda:
def validate_renavam(renavam):
if len(renavam) != 11:
renavam = str(renavam).rjust(11, '0')
Real, eu corrigi na codebase que uso e esqueci de corrigir por aqui. Muito obrigado
Validador em PHP (>= 8.0.0), implementando interface ValidationRule
do Laravel 11, baseado no código em https://victorjabur.com/2010/05/28/renavam_veiculos_java
<?php
namespace App\Rules;
use Closure;
use Illuminate\Contracts\Validation\ValidationRule;
class Renavam implements ValidationRule
{
/**
* Run the validation rule.
*
* @param \Closure(string, ?string=): \Illuminate\Translation\PotentiallyTranslatedString $fail
*/
public function validate(string $attribute, mixed $value, Closure $fail): void
{
if (!is_string($value)) {
$fail('Must be a string');
}
if (!is_numeric($value)) {
$fail('Must have only numbers');
}
$value = str_pad($value, 11, '0', STR_PAD_LEFT);
if (strlen($value) !== 11) {
$fail('Must have exactly 11 numbers');
}
[$numeros, $validador] = str_split($value, 10);
if ($this->calcularDigitos($numeros) !== $validador) {
$fail('Invalid Renavam');
}
}
private function calcularDigitos(string $numeros): string
{
$primeiro = $this->calcularDigitoUnico($numeros);
return '' . $primeiro;
}
private function calcularDigitoUnico(string $numeros): int
{
$numeros = strrev($numeros);
$length = strlen($numeros);
$sum = 0;
for ($i = 0; $i < $length; $i++) {
$sum += intval($numeros[$i]) * (2 + $i % 8);
}
$mod = $sum % 11;
return $mod < 2 ? 0 : 11 - $mod;
}
}
A lógica é igual à do CNPJ, diferindo apenas no tamanho do número e quantidade de dígitos verificadores.
Codei o exemplo a cima em Go
package main
import (
"fmt"
"regexp"
"strconv"
"strings"
)
func IsValidRenavam(input string) bool {
renavam := strings.TrimSpace(input)
renavam = normalizeOlderRenavam(renavam)
if !regexp.MustCompile(`^\d{11}$`).MatchString(renavam) {
return false
}
base := reverseString(renavam[:10])
multiplicadores := []int{2, 3, 4, 5, 6, 7, 8, 9, 2, 3}
soma := 0
for i := 0; i < 10; i++ {
num, _ := strconv.Atoi(string(base[i]))
soma += num * multiplicadores[i]
}
resto := soma % 11
digitoCalculado := 11 - resto
if digitoCalculado >= 10 {
digitoCalculado = 0
}
digitoInformado, _ := strconv.Atoi(string(renavam[10]))
return digitoCalculado == digitoInformado
}
func normalizeOlderRenavam(renavam string) string {
if regexp.MustCompile(`^\d{9}$`).MatchString(renavam) {
return "00" + renavam
}
return renavam
}
func reverseString(s string) string {
r := []rune(s)
for i, j := 0, len(r)-1; i < j; i, j = i+1, j-1 {
r[i], r[j] = r[j], r[i]
}
return string(r)
}
func main() {
// Exemplos de uso
fmt.Println(IsValidRenavam("77338872602")) // true
fmt.Println(IsValidRenavam("12345678909")) // false
fmt.Println(IsValidRenavam("65306981534")) // true
fmt.Println(IsValidRenavam("05115024925")) // false
}
use o playgorund de Go para testar: https://go.dev/play/
Codei o exemplo acima em TypeScript