Skip to content

Commit d8ab8a0

Browse files
carlos3dxcclauss
andauthored
Add Spain National ID validator (#7574) (#7575)
* Add Spain National ID validator (#7574) * is_spain_national_id() * Update is_spain_national_id.py * Some systems add a dash Co-authored-by: Christian Clauss <[email protected]>
1 parent bb07854 commit d8ab8a0

File tree

1 file changed

+72
-0
lines changed

1 file changed

+72
-0
lines changed

strings/is_spain_national_id.py

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
NUMBERS_PLUS_LETTER = "Input must be a string of 8 numbers plus letter"
2+
LOOKUP_LETTERS = "TRWAGMYFPDXBNJZSQVHLCKE"
3+
4+
5+
def is_spain_national_id(spanish_id: str) -> bool:
6+
"""
7+
Spain National Id is a string composed by 8 numbers plus a letter
8+
The letter in fact is not part of the ID, it acts as a validator,
9+
checking you didn't do a mistake when entering it on a system or
10+
are giving a fake one.
11+
12+
https://en.wikipedia.org/wiki/Documento_Nacional_de_Identidad_(Spain)#Number
13+
14+
>>> is_spain_national_id("12345678Z")
15+
True
16+
>>> is_spain_national_id("12345678z") # It is case-insensitive
17+
True
18+
>>> is_spain_national_id("12345678x")
19+
False
20+
>>> is_spain_national_id("12345678I")
21+
False
22+
>>> is_spain_national_id("12345678-Z") # Some systems add a dash
23+
True
24+
>>> is_spain_national_id("12345678")
25+
Traceback (most recent call last):
26+
...
27+
ValueError: Input must be a string of 8 numbers plus letter
28+
>>> is_spain_national_id("123456709")
29+
Traceback (most recent call last):
30+
...
31+
ValueError: Input must be a string of 8 numbers plus letter
32+
>>> is_spain_national_id("1234567--Z")
33+
Traceback (most recent call last):
34+
...
35+
ValueError: Input must be a string of 8 numbers plus letter
36+
>>> is_spain_national_id("1234Z")
37+
Traceback (most recent call last):
38+
...
39+
ValueError: Input must be a string of 8 numbers plus letter
40+
>>> is_spain_national_id("1234ZzZZ")
41+
Traceback (most recent call last):
42+
...
43+
ValueError: Input must be a string of 8 numbers plus letter
44+
>>> is_spain_national_id(12345678)
45+
Traceback (most recent call last):
46+
...
47+
TypeError: Expected string as input, found int
48+
"""
49+
50+
if not isinstance(spanish_id, str):
51+
raise TypeError(f"Expected string as input, found {type(spanish_id).__name__}")
52+
53+
spanish_id_clean = spanish_id.replace("-", "").upper()
54+
if len(spanish_id_clean) != 9:
55+
raise ValueError(NUMBERS_PLUS_LETTER)
56+
57+
try:
58+
number = int(spanish_id_clean[0:8])
59+
letter = spanish_id_clean[8]
60+
except ValueError as ex:
61+
raise ValueError(NUMBERS_PLUS_LETTER) from ex
62+
63+
if letter.isdigit():
64+
raise ValueError(NUMBERS_PLUS_LETTER)
65+
66+
return letter == LOOKUP_LETTERS[number % 23]
67+
68+
69+
if __name__ == "__main__":
70+
import doctest
71+
72+
doctest.testmod()

0 commit comments

Comments
 (0)