Skip to content

Commit

Permalink
improving is_valid cpf function (#79)
Browse files Browse the repository at this point in the history
* improving is_valid cpf function
* Refatorando a fun莽茫o is_valid_cpf
  • Loading branch information
antoniamaia committed May 13, 2023
1 parent 934f0f2 commit 3bbdbe4
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 15 deletions.
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ $ git clone git@github.com:brazilian-utils/brutils-python.git
$ cd brutils-python
```

Create a [virtualenv][virtualenv] for ScanAPI and activate it:
Create a [virtualenv][virtualenv] for brutils and activate it:

```shell
$ make shell
Expand Down
50 changes: 39 additions & 11 deletions brutils/cpf.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,20 +90,48 @@ def validate(cpf): # type: (str) -> bool
return all(hashdigit(cpf, i + 10) == int(v) for i, v in enumerate(cpf[9:]))


def is_valid(cpf): # type: (str) -> bool
"""
Returns whether or not the verifying checksum digits of the
given `cpf` match it's base number. Input should be a digit
string of proper length.
Using this method name to match with the js library api.
Using the same method to ensure backwards compatibility.
"""
return validate(cpf)


def generate(): # type: () -> str
"""Generates a random valid CPF digit string."""
base = str(randint(1, 999999998)).zfill(9)
while len(set(base)) == 1:
base = str(randint(1, 999999998)).zfill(9)
return base + checksum(base)


def is_valid(cpf): # type: (str) -> bool
"""
Returns whether or not a cpf is_valid.
Source: https://www.geradorcpf.com/algoritmo_do_cpf.htm
"""
is_syntax_valid = isinstance(cpf, str) and len(cpf) == 11 and cpf.isdigit()

return is_syntax_valid and _is_semantic_valid(cpf)


def _is_semantic_valid(cpf):
cpf = [int(digit) for digit in cpf]

constants_tenth_digit = [10, 9, 8, 7, 6, 5, 4, 3, 2]
is_tenth_digit_valid = _is_digit_valid(cpf, constants_tenth_digit, 9)

constants_eleventh_digit = [11, 10, 9, 8, 7, 6, 5, 4, 3, 2]
is_eleventh_digit_valid = _is_digit_valid(cpf, constants_eleventh_digit, 10)

return is_tenth_digit_valid and is_eleventh_digit_valid


def _is_digit_valid(cpf, constants, digit_index):
sum = _multiply_and_sum_lists(cpf, constants, digit_index)
rest = sum % 11
digit = cpf[digit_index]

return (rest <= 2 and digit == 0) or (rest > 2 and digit == (11 - rest))


def _multiply_and_sum_lists(list_1, list_2, max_index):
sum = 0

for index in range(0, max_index):
sum += list_1[index] * list_2[index]

return sum
27 changes: 24 additions & 3 deletions tests/test_cpf.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,30 @@ def test_validate(self):
assert not validate("00000000000")

def test_is_valid(self):
assert is_valid("52513127765")
assert is_valid("52599927765")
assert not is_valid("00000000000")
# When cpf is not string, returns False
assert not is_valid(1)

# When cpf's len is different of 11, returns False
assert not is_valid("1")

# When cpf does not contain only digits, returns False
assert not is_valid("1112223334-")

# When rest_1 is lt 2 and the 10th digit is not 0, returns False
assert not is_valid("11111111215")

# When rest_1 is gte 2 and the 10th digit is not (11 - rest), returns False
assert not is_valid("11144477705")

# When rest_2 is lt 2 and the 11th digit is not 0, returns False
assert not is_valid("11111111204")

# When rest_2 is gte 2 and the 11th digit is not (11 - rest), returns False
assert not is_valid("11144477732")

# When cpf is valid
assert is_valid("11144477735")
assert is_valid("11111111200")

def test_generate(self):
for i in range(1000):
Expand Down

0 comments on commit 3bbdbe4

Please sign in to comment.