From 9c7c669ece1491e7fd697f2184ad9b7185be59b2 Mon Sep 17 00:00:00 2001 From: Kevin Dagostino Date: Fri, 15 Dec 2023 12:59:26 -0500 Subject: [PATCH] Imporve French NIF validation (checksum) The last 3 digits are a checksum. % 511 https://ec.europa.eu/taxation_customs/tin/specs/FS-TIN%20Algorithms-Public.docx Closes https://github.com/arthurdejong/python-stdnum/pull/426 --- stdnum/fr/nif.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/stdnum/fr/nif.py b/stdnum/fr/nif.py index 4d57e4e4..d0436744 100644 --- a/stdnum/fr/nif.py +++ b/stdnum/fr/nif.py @@ -30,8 +30,12 @@ * https://ec.europa.eu/taxation_customs/tin/tinByCountry.html * https://fr.wikipedia.org/wiki/Numéro_d%27Immatriculation_Fiscale#France ->>> validate('0701987765432') -'0701987765432' +>>> validate('3023217600053') +'3023217600053' +>>> validate('3023217600054') +Traceback (most recent call last): + ... +InvalidChecksum: ... >>> validate('070198776543') Traceback (most recent call last): ... @@ -40,8 +44,8 @@ Traceback (most recent call last): ... InvalidComponent: ... ->>> format('0701987765432') -'07 01 987 765 432' +>>> format('3023217600053') +'30 23 217 600 053' """ from stdnum.exceptions import * @@ -54,6 +58,11 @@ def compact(number): return clean(number, ' ').strip() +def calc_check_digits(number): + """Calculate the check digits for the number.""" + return '%03d' % (int(number[:10]) % 511) + + def validate(number): """Check if the number provided is a valid NIF.""" number = compact(number) @@ -63,6 +72,8 @@ def validate(number): raise InvalidComponent() if len(number) != 13: raise InvalidLength() + if calc_check_digits(number) != number[-3:]: + raise InvalidChecksum() return number