Last active
June 20, 2025 04:39
-
-
Save cagartner/efe5e37c9c52063660cd to your computer and use it in GitHub Desktop.
Função para validar Renavam, Valida Renavam, Verifica Renavam
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/
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Real, eu corrigi na codebase que uso e esqueci de corrigir por aqui. Muito obrigado