0
# Internationalization Validation
1
2
Validators for country-specific personal and business identifiers. These validators implement local validation rules, check digits, and format requirements for national identification systems.
3
4
## Capabilities
5
6
### Spanish Identifiers
7
8
Validators for Spanish national identification documents and tax codes.
9
10
```python { .api }
11
def es_cif(value: str, /) -> Union[Literal[True], ValidationError]:
12
"""
13
Validate Spanish CIF (Código de Identificación Fiscal) - company tax ID.
14
15
Parameters:
16
- value: CIF string to validate
17
18
Returns:
19
True if valid CIF, ValidationError otherwise
20
21
Format: 8 characters + 1 check digit
22
- First character: Letter indicating organization type (A-N, P, Q, R, S, W)
23
- Next 7 characters: Numbers
24
- Last character: Check digit (letter or number)
25
26
Used for companies, associations, and other entities in Spain.
27
"""
28
29
def es_nif(value: str, /) -> Union[Literal[True], ValidationError]:
30
"""
31
Validate Spanish NIF (Número de Identificación Fiscal) - personal tax ID.
32
33
Parameters:
34
- value: NIF string to validate
35
36
Returns:
37
True if valid NIF, ValidationError otherwise
38
39
Format: 8 digits + 1 check letter
40
- 8 digits: Personal identification number
41
- 1 letter: Check letter calculated from the digits
42
43
Used for Spanish nationals and residents.
44
"""
45
46
def es_nie(value: str, /) -> Union[Literal[True], ValidationError]:
47
"""
48
Validate Spanish NIE (Número de Identidad de Extranjero) - foreigner ID.
49
50
Parameters:
51
- value: NIE string to validate
52
53
Returns:
54
True if valid NIE, ValidationError otherwise
55
56
Format: 1 letter + 7 digits + 1 check letter
57
- First letter: X, Y, or Z
58
- 7 digits: Sequential number
59
- Check letter: Calculated from the number
60
61
Used for foreigners with legal residence in Spain.
62
"""
63
64
def es_doi(value: str, /) -> Union[Literal[True], ValidationError]:
65
"""
66
Validate Spanish DOI (Documento de Identidad) - any Spanish digital identity.
67
68
Parameters:
69
- value: DOI string to validate
70
71
Returns:
72
True if valid DOI, ValidationError otherwise
73
74
Validates any of: NIF, NIE, or CIF
75
Used as a general validator for Spanish identification documents.
76
"""
77
```
78
79
### Finnish Identifiers
80
81
Validators for Finnish national identification and business codes.
82
83
```python { .api }
84
def fi_business_id(value: str, /) -> Union[Literal[True], ValidationError]:
85
"""
86
Validate Finnish business ID (Y-tunnus).
87
88
Parameters:
89
- value: Finnish business ID string to validate
90
91
Returns:
92
True if valid business ID, ValidationError otherwise
93
94
Format: 7 digits + hyphen + 1 check digit
95
- Example: 1234567-8
96
- Check digit calculated using modulo 11 algorithm
97
98
Used for all Finnish companies and organizations.
99
"""
100
101
def fi_ssn(value: str, /, *, allow_temporal_ssn: bool = True) -> Union[Literal[True], ValidationError]:
102
"""
103
Validate Finnish Social Security Number (Henkilötunnus).
104
105
Parameters:
106
- value: Finnish SSN string to validate
107
- allow_temporal_ssn: Allow temporal SSNs (900-999 birth numbers)
108
109
Returns:
110
True if valid SSN, ValidationError otherwise
111
112
Format: DDMMYY-NNNC or DDMMYY+NNNC or DDMMYYANNC
113
- DDMMYY: Birth date
114
- Separator: - (1900s), + (1800s), A (2000s)
115
- NNN: Individual number (002-899 normal, 900-999 temporal)
116
- C: Check character
117
118
Used for all Finnish residents.
119
"""
120
```
121
122
### French Identifiers
123
124
Validators for French national codes and administrative identifiers.
125
126
```python { .api }
127
def fr_department(value: Union[str, int], /) -> Union[Literal[True], ValidationError]:
128
"""
129
Validate French department numbers.
130
131
Parameters:
132
- value: Department number (string or integer)
133
134
Returns:
135
True if valid department number, ValidationError otherwise
136
137
Validates French administrative department codes:
138
- Metropolitan France: 01-95 (excluding 20)
139
- Corsica: 2A, 2B (or 201, 202)
140
- Overseas departments: 971, 972, 973, 974, 976
141
- Overseas collectivities: 975, 977, 978, 984-988
142
"""
143
144
def fr_ssn(value: str, /) -> Union[Literal[True], ValidationError]:
145
"""
146
Validate French Social Security Number (Numéro de Sécurité Sociale).
147
148
Parameters:
149
- value: French SSN string to validate
150
151
Returns:
152
True if valid SSN, ValidationError otherwise
153
154
Format: 15 digits (often displayed with spaces as groups)
155
- 1 digit: Gender (1=male, 2=female, 7-8=temporary)
156
- 2 digits: Birth year (last 2 digits)
157
- 2 digits: Birth month (01-12)
158
- 2 digits: Birth department
159
- 3 digits: Birth commune
160
- 3 digits: Birth order number
161
- 2 digits: Check digits (97 - (first 13 digits mod 97))
162
163
Also known as INSEE number.
164
"""
165
```
166
167
### Indian Identifiers
168
169
Validators for Indian national identification documents.
170
171
```python { .api }
172
def ind_aadhar(value: str, /) -> Union[Literal[True], ValidationError]:
173
"""
174
Validate Indian Aadhar card numbers.
175
176
Parameters:
177
- value: Aadhar number string to validate
178
179
Returns:
180
True if valid Aadhar number, ValidationError otherwise
181
182
Format: 12 digits
183
- No leading zeros in first digit
184
- Uses Verhoeff check digit algorithm
185
- Example: 1234 5678 9012
186
187
Unique identification number for Indian residents.
188
"""
189
190
def ind_pan(value: str, /) -> Union[Literal[True], ValidationError]:
191
"""
192
Validate Indian PAN (Permanent Account Number) card numbers.
193
194
Parameters:
195
- value: PAN string to validate
196
197
Returns:
198
True if valid PAN, ValidationError otherwise
199
200
Format: 10 characters (AAAAA9999A)
201
- First 5: Letters
202
- Next 4: Digits
203
- Last 1: Letter (check character)
204
- Example: ABCDE1234F
205
206
Used for tax identification in India.
207
"""
208
```
209
210
### Russian Identifiers
211
212
Validators for Russian tax and business identifiers.
213
214
```python { .api }
215
def ru_inn(value: str, /) -> Union[Literal[True], ValidationError]:
216
"""
217
Validate Russian INN (Individual Taxpayer Number).
218
219
Parameters:
220
- value: INN string to validate
221
222
Returns:
223
True if valid INN, ValidationError otherwise
224
225
Formats:
226
- 10 digits: Legal entities (companies)
227
- 12 digits: Individual taxpayers
228
229
Uses specific check digit algorithms for validation.
230
Required for all Russian taxpayers.
231
"""
232
```
233
234
## Usage Examples
235
236
```python
237
import validators
238
239
# Spanish identifiers
240
validators.es_nif('12345678Z') # True (personal tax ID)
241
validators.es_nie('X1234567L') # True (foreigner ID)
242
validators.es_cif('A12345674') # True (company tax ID)
243
validators.es_doi('12345678Z') # True (validates any Spanish ID)
244
245
# Finnish identifiers
246
validators.fi_business_id('1234567-8') # True
247
validators.fi_ssn('311280-999J') # True
248
validators.fi_ssn('311280-999J', allow_temporal_ssn=False) # May be False if temporal
249
250
# French identifiers
251
validators.fr_department('75') # True (Paris)
252
validators.fr_department(75) # True (accepts int)
253
validators.fr_department('2A') # True (Corsica)
254
validators.fr_ssn('123456789012345') # True (if valid checksum)
255
256
# Indian identifiers
257
validators.ind_aadhar('123456789012') # True (if valid Verhoeff check)
258
validators.ind_pan('ABCDE1234F') # True
259
260
# Russian identifiers
261
validators.ru_inn('1234567890') # True (10-digit legal entity)
262
validators.ru_inn('123456789012') # True (12-digit individual)
263
```
264
265
## Advanced Usage
266
267
### Multi-Country ID Validation
268
269
```python
270
import validators
271
272
def validate_national_id(country: str, id_value: str) -> dict:
273
"""Validate national ID based on country."""
274
275
country_validators = {
276
'ES': {
277
'nif': validators.es_nif,
278
'nie': validators.es_nie,
279
'cif': validators.es_cif,
280
'any': validators.es_doi
281
},
282
'FI': {
283
'ssn': validators.fi_ssn,
284
'business': validators.fi_business_id
285
},
286
'FR': {
287
'ssn': validators.fr_ssn,
288
},
289
'IN': {
290
'aadhar': validators.ind_aadhar,
291
'pan': validators.ind_pan
292
},
293
'RU': {
294
'inn': validators.ru_inn
295
}
296
}
297
298
if country not in country_validators:
299
return {'supported': False, 'results': {}}
300
301
results = {}
302
for id_type, validator in country_validators[country].items():
303
results[id_type] = bool(validator(id_value))
304
305
return {
306
'supported': True,
307
'results': results,
308
'any_valid': any(results.values())
309
}
310
311
# Usage
312
result = validate_national_id('ES', '12345678Z')
313
print(f"Spanish ID validation: {result}")
314
```
315
316
### ID Format Detection
317
318
```python
319
import validators
320
321
def detect_id_format(id_value: str) -> list:
322
"""Detect possible ID formats for a given value."""
323
324
possible_formats = []
325
326
# Test against all available validators
327
validators_to_test = [
328
('Spanish NIF', validators.es_nif),
329
('Spanish NIE', validators.es_nie),
330
('Spanish CIF', validators.es_cif),
331
('Finnish SSN', validators.fi_ssn),
332
('Finnish Business', validators.fi_business_id),
333
('French SSN', validators.fr_ssn),
334
('Indian Aadhar', validators.ind_aadhar),
335
('Indian PAN', validators.ind_pan),
336
('Russian INN', validators.ru_inn),
337
]
338
339
for format_name, validator in validators_to_test:
340
if validator(id_value):
341
possible_formats.append(format_name)
342
343
return possible_formats
344
345
# Usage
346
test_ids = [
347
'12345678Z', # Spanish NIF format
348
'X1234567L', # Spanish NIE format
349
'1234567-8', # Finnish business ID format
350
'ABCDE1234F', # Indian PAN format
351
]
352
353
for test_id in test_ids:
354
formats = detect_id_format(test_id)
355
print(f"{test_id}: {formats}")
356
```
357
358
## Validation Rules Summary
359
360
### Check Digit Algorithms Used
361
362
- **Spanish NIF/NIE**: Modulo 23 with letter mapping
363
- **Spanish CIF**: Complex algorithm based on organization type
364
- **Finnish Business ID**: Modulo 11 algorithm
365
- **Finnish SSN**: Modulo 31 with character mapping
366
- **French SSN**: Modulo 97 algorithm
367
- **Indian Aadhar**: Verhoeff algorithm
368
- **Indian PAN**: Format validation only
369
- **Russian INN**: Specific algorithms for 10/12 digit formats
370
371
### Common Validation Patterns
372
373
```python
374
import validators
375
376
# Batch validation example
377
identifiers = [
378
('ES', 'NIF', '12345678Z'),
379
('FI', 'SSN', '311280-999J'),
380
('IN', 'PAN', 'ABCDE1234F'),
381
('RU', 'INN', '1234567890'),
382
]
383
384
for country, type_name, id_value in identifiers:
385
# Try to validate based on country and type
386
is_valid = False
387
388
if country == 'ES' and type_name == 'NIF':
389
is_valid = bool(validators.es_nif(id_value))
390
elif country == 'FI' and type_name == 'SSN':
391
is_valid = bool(validators.fi_ssn(id_value))
392
elif country == 'IN' and type_name == 'PAN':
393
is_valid = bool(validators.ind_pan(id_value))
394
elif country == 'RU' and type_name == 'INN':
395
is_valid = bool(validators.ru_inn(id_value))
396
397
print(f"{country} {type_name} {id_value}: {'✓' if is_valid else '✗'}")
398
```