-
Notifications
You must be signed in to change notification settings - Fork 51
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #23 from beatrizuezu/cnh-validation
Add validation for CNH
- Loading branch information
Showing
4 changed files
with
112 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import unittest | ||
import validate_docbr as docbr | ||
|
||
|
||
class TestCnh(unittest.TestCase): | ||
"""Testar a classe CNH.""" | ||
|
||
def setUp(self): | ||
"""Inicia novo objeto em todo os testes.""" | ||
self.cnh = docbr.CNH() | ||
|
||
def test_generate_validate(self): | ||
"""Verifica os métodos de geração e validação de documento.""" | ||
# generate_list | ||
cnhs = ( | ||
self.cnh.generate_list(1) | ||
+ self.cnh.generate_list(1, mask=True) | ||
+ self.cnh.generate_list(1, mask=True, repeat=True) | ||
) | ||
self.assertIsInstance(cnhs, list) | ||
self.assertTrue(len(cnhs) == 3) | ||
|
||
# validate_list | ||
cnhs_validates = self.cnh.validate_list(cnhs) | ||
self.assertTrue(sum(cnhs_validates) == 3) | ||
|
||
def test_mask(self): | ||
"""Verifica se o método mask funciona corretamente.""" | ||
masked_cpf = self.cnh.mask('11122233344') | ||
self.assertEqual(masked_cpf, '111 222 333 44') | ||
|
||
def test_special_case(self): | ||
""" Verifica os casos especiais de CNH """ | ||
cases = [ | ||
('00000000000', False), | ||
('78623161668', False), | ||
('0123 456 789 10', False), | ||
('65821310502', True), | ||
('658 213 105 02', True), | ||
] | ||
for cnh, is_valid in cases: | ||
self.assertEqual(self.cnh.validate(cnh), is_valid) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
from .BaseDoc import BaseDoc | ||
from random import sample | ||
from typing import List | ||
|
||
|
||
class CNH(BaseDoc): | ||
"""Classe referente ao Carteira Nacional de Habilitação (CNH).""" | ||
|
||
def __init__(self): | ||
self.digits = list(range(10)) | ||
self.dsc = 0 | ||
|
||
def validate(self, doc: str = '') -> bool: | ||
"""Validar CNH.""" | ||
doc = self._only_digits(doc) | ||
|
||
if len(doc) != 11 or self._is_repeated_digits(doc): | ||
return False | ||
|
||
first_digit = self._generate_first_digit(doc) | ||
second_digit = self._generate_second_digit(doc) | ||
|
||
return first_digit == doc[9] and second_digit == doc[10] | ||
|
||
def generate(self, mask: bool = False) -> str: | ||
"""Gerar CNH.""" | ||
cnh = [str(sample(self.digits, 1)[0]) for i in range(9)] | ||
cnh.append(self._generate_first_digit(cnh)) | ||
cnh.append(self._generate_second_digit(cnh)) | ||
|
||
cnh = ''.join(cnh) | ||
return self.mask(cnh) if mask else cnh | ||
|
||
def mask(self, doc: str = '') -> str: | ||
"""Coloca a máscara de CNH na variável doc.""" | ||
return f'{doc[:3]} {doc[3:6]} {doc[6:9]} {doc[9:]}' | ||
|
||
def _generate_first_digit(self, doc: list) -> tuple: | ||
"""Gerar o primeiro dígito verificador da CNH.""" | ||
sum = 0 | ||
|
||
for i in range(9, 0, -1): | ||
sum += int(doc[9 - i]) * i | ||
|
||
first_value = sum % 11 | ||
if first_value >= 10: | ||
first_value, self.dsc = 0, 2 | ||
return str(first_value) | ||
|
||
def _generate_second_digit(self, doc: list) -> str: | ||
"""Gerar o segundo dígito verificador da CNH.""" | ||
sum = 0 | ||
|
||
for i in range(1, 10): | ||
sum += int(doc[i-1]) * i | ||
|
||
rest = sum % 11 | ||
|
||
second_value = rest - self.dsc | ||
if rest >= 10: | ||
second_value = 0 | ||
return str(second_value) | ||
|
||
def _is_repeated_digits(self, doc: List[str]) -> bool: | ||
"""Verifica se é uma CNH contém com números repetidos. | ||
Exemplo: 11111111111""" | ||
return len(set(doc)) == 1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
from .BaseDoc import BaseDoc | ||
from .CPF import CPF | ||
from .CNPJ import CNPJ | ||
from .CNH import CNH | ||
from .CNS import CNS |