@@ -0,0 +1,2808 @@
+# nir.py - functions for handling French NIR numbers%0A#%0A# Copyright (C) 2016 Dimitri Papadopoulos%0A#%0A# This library is free software; you can redistribute it and/or%0A# modify it under the terms of the GNU Lesser General Public%0A# License as published by the Free Software Foundation; either%0A# version 2.1 of the License, or (at your option) any later version.%0A#%0A# This library is distributed in the hope that it will be useful,%0A# but WITHOUT ANY WARRANTY; without even the implied warranty of%0A# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU%0A# Lesser General Public License for more details.%0A#%0A# You should have received a copy of the GNU Lesser General Public%0A# License along with this library; if not, write to the Free Software%0A# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA%0A# 02110-1301 USA%0A%0A%22%22%22NIR (French personal identification number).%0A%0AThe NIR (Numero d'Inscription au Repertoire national d'identification%0Ades personnes physiques) is a 15 digit number used to identify persons%0Ain France. All persons born in France are registered in the Repertoire%0Anational d'identification des personnes physiques (RNIPP) and assigned%0Aa NIR which consists of 15 digits where the two final digits are check%0Adigits. The NIR is used by French social security and is popularly known%0Aas the %22social security number%22.%0A%0AMore information:%0A%0A* http://www.insee.fr/en/methodes/default.asp?page=definitions/nir.htm%0A%0A%3E%3E%3E validate('2 95 10 99 126 111 93')%0A'295109912611193'%0A%3E%3E%3E validate('295109912611199')  # invalid check digit%0ATraceback (most recent call last):%0A    ...%0AInvalidChecksum: ...%0A%3E%3E%3E format('295109912611193')%0A'2 95 10 99 126 111 93'%0A%22%22%22%0A%0Afrom stdnum.exceptions import *%0Afrom stdnum.util import clean%0A%0A%0Adef compact(number):%0A    %22%22%22Convert the number to the minimal representation. This strips the%0A    number of any valid separators and removes surrounding whitespace.%22%22%22%0A    return clean(number, ' .').strip()%0A%0A%0Adef validate(number):%0A    %22%22%22Checks to see if the number provided is valid. This checks the length%0A    and check digit.%22%22%22%0A    number = compact(number)%0A    if not number.isdigit():%0A        raise InvalidFormat()%0A    if len(number) != 15:%0A        raise InvalidLength()%0A    if (97 - (int(number%5B:13%5D) %25 97)) != int(number%5B13:%5D):%0A        raise InvalidChecksum()%0A    return number%0A%0A%0Adef is_valid(number):%0A    %22%22%22Checks to see if the number provided is valid. This checks the length%0A    and check digit.%22%22%22%0A    try:%0A        return bool(validate(number))%0A    except ValidationError:%0A        return False%0A%0A%0Adef format(number, separator=' '):%0A    %22%22%22Reformat the passed number to the standard format.%22%22%22%0A    number = compact(number)%0A    return separator.join((number%5B:1%5D, number%5B1:3%5D, number%5B3:5%5D, number%5B5:7%5D,%0A                           number%5B7:10%5D, number%5B10:13%5D, number%5B13:%5D))%0A

Add French NIR