Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Utilitário `convert_name_to_uf`
- Utilitário `is_valid_cnh` [#651](https://github.com/brazilian-utils/brutils-python/pull/651)
- Utilitário `is_valid_renavam` [#652](https://github.com/brazilian-utils/brutils-python/pull/652)

### Fixed

Expand Down
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ False
- [format\_legal\_process](#format_legal_process)
- [remove\_symbols\_legal\_process](#remove_symbols_legal_process)
- [generate\_legal\_process](#generate_legal_process)
- [RENAVAM](#renavam)
- [is_valid_renavam](#is_valid_renavam)
- [Titulo Eleitoral](#titulo-eleitoral)
- [is\_valid\_voter\_id](#is_valid_voter_id)
- [format\_voter\_id](#format_voter_id)
Expand Down Expand Up @@ -1375,6 +1377,33 @@ Exemplo:
None
```

## RENAVAM

### is_valid_renavam

Valida se os dígitos de verificação do RENAVAM fornecido
correspondem aos seus 10 dígitos iniciais. Esta função não verifica a existência do veículo;
ela apenas valida o formato da string e o dígito verificador.

Argumentos:

- renavam (str): O RENAVAM a ser validado, uma string de 11 dígitos.

Retorna:

- bool: Verdadeiro se o RENAVAM for válido
Falso caso contrário.

Exemplo:

```python
>>> from brutils import is_valid_renavam
>>> is_valid_renavam("86769597308")
True
>>> is_valid_renavam("12345678901")
False
```

# Novos Utilitários e Reportar Bugs

Caso queira sugerir novas funcionalidades ou reportar bugs, basta criar
Expand Down
28 changes: 28 additions & 0 deletions README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ False
- [format\_pis](#format_pis)
- [remove\_symbols\_pis](#remove_symbols_pis)
- [generate\_pis](#generate_pis)
- [RENAVAM](#renavam)
- [is_valid_renavam](#is_valid_renavam)
- [Legal Process](#legal-process)
- [is\_valid\_legal\_process](#is_valid_legal_process)
- [format\_legal\_process](#format_legal_process)
Expand Down Expand Up @@ -1379,6 +1381,32 @@ Example:
None
```

## RENAVAM

### is_valid_renavam

Validates whether the verification digit of the given RENAVAM
matches its first 10 digits. This function does not check if the vehicle exists;
it only validates the string format and the verification digit.

Arguments:

- renavam (str): The RENAVAM to be validated, a string of 11 digits.

Returns:

- bool: True if RENAVAM is valid,
False otherwise.

Example:

```python
>>> from brutils import is_valid_renavam
>>> is_valid_renavam("86769597308")
True
>>> is_valid_renavam("12345678901")
False

# Feature Request and Bug Report

If you want to suggest new features or report bugs, simply create
Expand Down
5 changes: 5 additions & 0 deletions brutils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@
from brutils.pis import is_valid as is_valid_pis
from brutils.pis import remove_symbols as remove_symbols_pis

# RENAVAM Imports
from brutils.renavam import is_valid_renavam

# Voter ID Imports
from brutils.voter_id import format_voter_id
from brutils.voter_id import generate as generate_voter_id
Expand Down Expand Up @@ -125,6 +128,8 @@
"generate_pis",
"is_valid_pis",
"remove_symbols_pis",
# RENAVAM
"is_valid_renavam",
# Voter ID
"format_voter_id",
"generate_voter_id",
Expand Down
56 changes: 56 additions & 0 deletions brutils/renavam.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
RENAVAM_DV_WEIGHTS = [2, 3, 4, 5, 6, 7, 8, 9, 2, 3]


def _validate_renavam_format(renavam: str):
if not isinstance(renavam, str):
return False
if len(renavam) != 11 or not renavam.isdigit():
return False
if len(set(renavam)) == 1:
return False
return True


def _sum_weighted_digits(renavam: str) -> int:
base_digits = [int(d) for d in renavam[:-1][::-1]]
return sum(x * y for x, y in zip(base_digits, RENAVAM_DV_WEIGHTS))


def _calculate_renavam_dv(renavam: str):
weighted_sum = _sum_weighted_digits(renavam)
dv = 11 - (weighted_sum % 11)
return 0 if dv >= 10 else dv


def is_valid_renavam(renavam: str) -> bool:
"""
Validates the Brazilian vehicle registration number (RENAVAM).

This function takes a RENAVAM string and checks if it is valid.
A valid RENAVAM consists of exactly 11 digits, with the last digit as
a verification digit calculated from the previous 10 digits.

Args:
renavam (str): The RENAVAM string to be validated.

Returns:
bool: True if the RENAVAM is valid, False otherwise.

Example:
>>> is_valid_renavam('86769597308')
True
>>> is_valid_renavam('12345678901')
False
>>> is_valid_renavam('1234567890a')
False
>>> is_valid_renavam('12345678 901')
False
>>> is_valid_renavam('12345678')
False
>>> is_valid_renavam('')
False
"""
if not _validate_renavam_format(renavam):
return False

return _calculate_renavam_dv(renavam) == int(renavam[-1])
18 changes: 18 additions & 0 deletions tests/test_renavam.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from unittest import TestCase

from brutils.renavam import is_valid_renavam


class TestRENAVAM(TestCase):
def test_is_valid_renavam(self):
self.assertTrue(is_valid_renavam("86769597308"))
self.assertFalse(is_valid_renavam("12345678901"))
self.assertFalse(is_valid_renavam("1234567890a"))
self.assertFalse(is_valid_renavam("12345678 901"))
self.assertFalse(is_valid_renavam("12345678"))
self.assertFalse(is_valid_renavam(""))
self.assertFalse(is_valid_renavam("123456789012"))
self.assertFalse(is_valid_renavam("abcdefghijk"))
self.assertFalse(is_valid_renavam("12345678901!"))
self.assertFalse(is_valid_renavam("00000000000"))
self.assertFalse(is_valid_renavam("11111111111"))