Skip to content

Commit 178ebd9

Browse files
feat: renavam add is_valid_renavam function with validation, tests, and docs (#652)
* feat(renavam): add is_valid_renavam function with validation, tests, and docs * docs: include renavam in readme_en * style: apply formatting * fix: Removed Raise ValueError() to return False. Updated unit tests and documentation * fix: include function in section unreleased and remove empty line --------- Co-authored-by: Nilton Pimentel <63605485+niltonpimentel02@users.noreply.github.com>
1 parent 38e5b3e commit 178ebd9

6 files changed

Lines changed: 137 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1111

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

1516
### Fixed
1617

README.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ False
8888
- [format\_legal\_process](#format_legal_process)
8989
- [remove\_symbols\_legal\_process](#remove_symbols_legal_process)
9090
- [generate\_legal\_process](#generate_legal_process)
91+
- [RENAVAM](#renavam)
92+
- [is_valid_renavam](#is_valid_renavam)
9193
- [Titulo Eleitoral](#titulo-eleitoral)
9294
- [is\_valid\_voter\_id](#is_valid_voter_id)
9395
- [format\_voter\_id](#format_voter_id)
@@ -1375,6 +1377,33 @@ Exemplo:
13751377
None
13761378
```
13771379

1380+
## RENAVAM
1381+
1382+
### is_valid_renavam
1383+
1384+
Valida se os dígitos de verificação do RENAVAM fornecido
1385+
correspondem aos seus 10 dígitos iniciais. Esta função não verifica a existência do veículo;
1386+
ela apenas valida o formato da string e o dígito verificador.
1387+
1388+
Argumentos:
1389+
1390+
- renavam (str): O RENAVAM a ser validado, uma string de 11 dígitos.
1391+
1392+
Retorna:
1393+
1394+
- bool: Verdadeiro se o RENAVAM for válido
1395+
Falso caso contrário.
1396+
1397+
Exemplo:
1398+
1399+
```python
1400+
>>> from brutils import is_valid_renavam
1401+
>>> is_valid_renavam("86769597308")
1402+
True
1403+
>>> is_valid_renavam("12345678901")
1404+
False
1405+
```
1406+
13781407
# Novos Utilitários e Reportar Bugs
13791408

13801409
Caso queira sugerir novas funcionalidades ou reportar bugs, basta criar

README_EN.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ False
8282
- [format\_pis](#format_pis)
8383
- [remove\_symbols\_pis](#remove_symbols_pis)
8484
- [generate\_pis](#generate_pis)
85+
- [RENAVAM](#renavam)
86+
- [is_valid_renavam](#is_valid_renavam)
8587
- [Legal Process](#legal-process)
8688
- [is\_valid\_legal\_process](#is_valid_legal_process)
8789
- [format\_legal\_process](#format_legal_process)
@@ -1379,6 +1381,32 @@ Example:
13791381
None
13801382
```
13811383

1384+
## RENAVAM
1385+
1386+
### is_valid_renavam
1387+
1388+
Validates whether the verification digit of the given RENAVAM
1389+
matches its first 10 digits. This function does not check if the vehicle exists;
1390+
it only validates the string format and the verification digit.
1391+
1392+
Arguments:
1393+
1394+
- renavam (str): The RENAVAM to be validated, a string of 11 digits.
1395+
1396+
Returns:
1397+
1398+
- bool: True if RENAVAM is valid,
1399+
False otherwise.
1400+
1401+
Example:
1402+
1403+
```python
1404+
>>> from brutils import is_valid_renavam
1405+
>>> is_valid_renavam("86769597308")
1406+
True
1407+
>>> is_valid_renavam("12345678901")
1408+
False
1409+
13821410
# Feature Request and Bug Report
13831411

13841412
If you want to suggest new features or report bugs, simply create

brutils/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@
7474
from brutils.pis import is_valid as is_valid_pis
7575
from brutils.pis import remove_symbols as remove_symbols_pis
7676

77+
# RENAVAM Imports
78+
from brutils.renavam import is_valid_renavam
79+
7780
# Voter ID Imports
7881
from brutils.voter_id import format_voter_id
7982
from brutils.voter_id import generate as generate_voter_id
@@ -125,6 +128,8 @@
125128
"generate_pis",
126129
"is_valid_pis",
127130
"remove_symbols_pis",
131+
# RENAVAM
132+
"is_valid_renavam",
128133
# Voter ID
129134
"format_voter_id",
130135
"generate_voter_id",

brutils/renavam.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
RENAVAM_DV_WEIGHTS = [2, 3, 4, 5, 6, 7, 8, 9, 2, 3]
2+
3+
4+
def _validate_renavam_format(renavam: str):
5+
if not isinstance(renavam, str):
6+
return False
7+
if len(renavam) != 11 or not renavam.isdigit():
8+
return False
9+
if len(set(renavam)) == 1:
10+
return False
11+
return True
12+
13+
14+
def _sum_weighted_digits(renavam: str) -> int:
15+
base_digits = [int(d) for d in renavam[:-1][::-1]]
16+
return sum(x * y for x, y in zip(base_digits, RENAVAM_DV_WEIGHTS))
17+
18+
19+
def _calculate_renavam_dv(renavam: str):
20+
weighted_sum = _sum_weighted_digits(renavam)
21+
dv = 11 - (weighted_sum % 11)
22+
return 0 if dv >= 10 else dv
23+
24+
25+
def is_valid_renavam(renavam: str) -> bool:
26+
"""
27+
Validates the Brazilian vehicle registration number (RENAVAM).
28+
29+
This function takes a RENAVAM string and checks if it is valid.
30+
A valid RENAVAM consists of exactly 11 digits, with the last digit as
31+
a verification digit calculated from the previous 10 digits.
32+
33+
Args:
34+
renavam (str): The RENAVAM string to be validated.
35+
36+
Returns:
37+
bool: True if the RENAVAM is valid, False otherwise.
38+
39+
Example:
40+
>>> is_valid_renavam('86769597308')
41+
True
42+
>>> is_valid_renavam('12345678901')
43+
False
44+
>>> is_valid_renavam('1234567890a')
45+
False
46+
>>> is_valid_renavam('12345678 901')
47+
False
48+
>>> is_valid_renavam('12345678')
49+
False
50+
>>> is_valid_renavam('')
51+
False
52+
"""
53+
if not _validate_renavam_format(renavam):
54+
return False
55+
56+
return _calculate_renavam_dv(renavam) == int(renavam[-1])

tests/test_renavam.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from unittest import TestCase
2+
3+
from brutils.renavam import is_valid_renavam
4+
5+
6+
class TestRENAVAM(TestCase):
7+
def test_is_valid_renavam(self):
8+
self.assertTrue(is_valid_renavam("86769597308"))
9+
self.assertFalse(is_valid_renavam("12345678901"))
10+
self.assertFalse(is_valid_renavam("1234567890a"))
11+
self.assertFalse(is_valid_renavam("12345678 901"))
12+
self.assertFalse(is_valid_renavam("12345678"))
13+
self.assertFalse(is_valid_renavam(""))
14+
self.assertFalse(is_valid_renavam("123456789012"))
15+
self.assertFalse(is_valid_renavam("abcdefghijk"))
16+
self.assertFalse(is_valid_renavam("12345678901!"))
17+
self.assertFalse(is_valid_renavam("00000000000"))
18+
self.assertFalse(is_valid_renavam("11111111111"))

0 commit comments

Comments
 (0)