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