-
-
Save cagartner/efe5e37c9c52063660cd to your computer and use it in GitHub Desktop.
@LucasAndrad consegue ver se esse aqui funciona? http://geradorbrasileiro.com/renavam.html
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
Codei o exemplo em python do @EduardoJM em C#
public static bool IsValidRenavam(string renavam)
{
if (renavam.Length != 11)
{
renavam = renavam.PadRight(11, '0');
}
if (!Regex.IsMatch(renavam, "^[0-9]{11}$")) return false;
int[] digitos = GetDigitosInvertidos(renavam);
var verificador = GetDigitoVerificador(renavam);
var soma = GetSoma(digitos);
var verificadorCalculado = GetVerificador(soma);
return verificadorCalculado == verificador;
}
private static int[] GetDigitosInvertidos(string digitos)
{
char[] digitosChar = digitos.ToCharArray();
Array.Reverse(digitosChar);
return Array.ConvertAll(digitosChar, c => (int)Char.GetNumericValue(c));
}
private static int GetDigitoVerificador(string digitos)
{
string digito = digitos[-1].ToString();
return int.Parse(digito);
}
private static int GetSoma(int[] digitos)
{
var soma = 0;
for (var i = 0; i < digitos.Length; i++)
{
soma += digitos[i] * GetFactor(i);
}
return soma;
}
private static int GetFactor(int num)
{
int[] digits = { 2, 3, 4, 5, 6, 7, 8, 9 };
int index;
if (num >= digits.Length)
{
index = num % digits.Length;
}
else
{
index = num;
}
return digits[index];
}
private static int GetVerificador (int soma)
{
var valor = 11 - (soma % 11);
if (valor >= 10) return 0;
return valor;
}
Codei o exemplo acima em TypeScript
export class RenavamService {
public analyzeRenavam(renavam: string | number): boolean {
if (!renavam) {
return false;
}
const renavamParaString = renavam.toString();
const renavamNormalizado = this.normalizeOlderRenavam(renavamParaString);
if (renavamNormalizado.length !== 11) {
return false;
}
const renavamSemDigito = renavamNormalizado.substring(0, 10);
const renavamReversoSemDigito = renavamSemDigito.split('').reverse().join('');
let soma = 0;
for (let i = 0; i < 8; i++) {
let algarismo = Number(renavamReversoSemDigito[i]);
let multiplicador = i + 2;
soma += algarismo * multiplicador;
}
soma += Number(renavamReversoSemDigito.charAt(8)) * 2;
soma += Number(renavamReversoSemDigito.charAt(9)) * 3;
const mod11 = soma % 11;
let ultimoDigitoCalculado = 11 - mod11;
ultimoDigitoCalculado = ultimoDigitoCalculado >= 10 ? 0 : ultimoDigitoCalculado;
const digitoRealInformado = Number(
renavamParaString.substring(renavamParaString.length - 1, renavamParaString.length),
);
if (ultimoDigitoCalculado == digitoRealInformado) {
return true;
}
return false;
}
public normalizeOlderRenavam(renavam: string): string {
if (renavam.match('^([0-9]{9})$')) {
renavam = '00' + renavam;
}
return renavam;
}
}
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/
Testei alguns valores aqui e não de certo a função em JS
Peguei os valores nesse site 4devs e também testei com os valores dos carros aqui de casa, nenhum deu certo