Skip to content

Commit 9de1c49

Browse files
Mrk-Mzjcclausspre-commit-ci[bot]
authored
feat: Polish ID (PESEL) checker added (TheAlgorithms#10618)
* feat: Polish ID (PESEL) checker added * refactor: 'sum' variable renamed to 'subtotal' * style: typos * Apply suggestions from code review * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: Christian Clauss <[email protected]> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 09c2b2d commit 9de1c49

File tree

1 file changed

+92
-0
lines changed

1 file changed

+92
-0
lines changed

strings/is_polish_national_id.py

+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
def is_polish_national_id(input_str: str) -> bool:
2+
"""
3+
Verification of the correctness of the PESEL number.
4+
www-gov-pl.translate.goog/web/gov/czym-jest-numer-pesel?_x_tr_sl=auto&_x_tr_tl=en
5+
6+
PESEL can start with 0, that's why we take str as input,
7+
but convert it to int for some calculations.
8+
9+
10+
>>> is_polish_national_id(123)
11+
Traceback (most recent call last):
12+
...
13+
ValueError: Expected str as input, found <class 'int'>
14+
15+
>>> is_polish_national_id("abc")
16+
Traceback (most recent call last):
17+
...
18+
ValueError: Expected number as input
19+
20+
>>> is_polish_national_id("02070803628") # correct PESEL
21+
True
22+
23+
>>> is_polish_national_id("02150803629") # wrong month
24+
False
25+
26+
>>> is_polish_national_id("02075503622") # wrong day
27+
False
28+
29+
>>> is_polish_national_id("-99012212349") # wrong range
30+
False
31+
32+
>>> is_polish_national_id("990122123499999") # wrong range
33+
False
34+
35+
>>> is_polish_national_id("02070803621") # wrong checksum
36+
False
37+
"""
38+
39+
# check for invalid input type
40+
if not isinstance(input_str, str):
41+
msg = f"Expected str as input, found {type(input_str)}"
42+
raise ValueError(msg)
43+
44+
# check if input can be converted to int
45+
try:
46+
input_int = int(input_str)
47+
except ValueError:
48+
msg = "Expected number as input"
49+
raise ValueError(msg)
50+
51+
# check number range
52+
if not 10100000 <= input_int <= 99923199999:
53+
return False
54+
55+
# check month correctness
56+
month = int(input_str[2:4])
57+
58+
if (
59+
month not in range(1, 13) # year 1900-1999
60+
and month not in range(21, 33) # 2000-2099
61+
and month not in range(41, 53) # 2100-2199
62+
and month not in range(61, 73) # 2200-2299
63+
and month not in range(81, 93) # 1800-1899
64+
):
65+
return False
66+
67+
# check day correctness
68+
day = int(input_str[4:6])
69+
70+
if day not in range(1, 32):
71+
return False
72+
73+
# check the checksum
74+
multipliers = [1, 3, 7, 9, 1, 3, 7, 9, 1, 3]
75+
subtotal = 0
76+
77+
digits_to_check = str(input_str)[:-1] # cut off the checksum
78+
79+
for index, digit in enumerate(digits_to_check):
80+
# Multiply corresponding digits and multipliers.
81+
# In case of a double-digit result, add only the last digit.
82+
subtotal += (int(digit) * multipliers[index]) % 10
83+
84+
checksum = 10 - subtotal % 10
85+
86+
return checksum == input_int % 10
87+
88+
89+
if __name__ == "__main__":
90+
from doctest import testmod
91+
92+
testmod()

0 commit comments

Comments
 (0)