8000 Add Belgian National Number · unho/python-stdnum@dcf4730 · GitHub
[go: up one dir, main page]

Skip to content

Commit dcf4730

Browse files
cedkarthurdejong
authored andcommitted
Add Belgian National Number
Closes arthurdejong#284
1 parent 50650a9 commit dcf4730

File tree

2 files changed

+94
-0
lines changed

2 files changed

+94
-0
lines changed

stdnum/be/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,5 @@
2121
"""Collection of Belgian numbers."""
2222

2323
# provide businessid as an alias
24+
from stdnum.be import nn as personalid # noqa: F401
2425
from stdnum.be import vat as businessid # noqa: F401

stdnum/be/nn.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# coding=utf-8
2+
# nn.py - function for handling Belgian national numbers
3+
#
4+
# Copyright (C) 2021 Cédric Krier
5+
#
6+
# This library is free software; you can redistribute it and/or
7+
# modify it under the terms of the GNU Lesser General Public
8+
# License as published by the Free Software Foundation; either
9+
# version 2.1 of the License, or (at your option) any later version.
10+
#
11+
# This library is distributed in the hope that it will be useful,
12+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
# Lesser General Public License for more details.
15+
#
16+
# You should have received a copy of the GNU Lesser General Public
17+
# License along with this library; if not, write to the Free Software
18+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19+
# 02110-1301 USA
20+
21+
"""NN, NISS (Belgian national number).
22+
23+
The national number is a unique identifier of Belgian. The number consists of
24+
11 digits.
25+
26+
More information:
27+
28+
* https://fr.wikipedia.org/wiki/Numéro_de_registre_national
29+
30+
>>> compact('85.07.30-033 28')
31+
'85073003328'
32+
>>> validate('85 07 30 033 28')
33+
'85073003328'
34+
>>> validate('17 07 30 033 84')
35+
'17073003384'
36+
>>> validate('12345678901')
37+
Traceback (most recent call last):
38+
...
39+
InvalidChecksum: ...
40+
>>> format('85073003328')
41+
'85.07.30-033.28'
42+
"""
43+
44+
import datetime
45+
46+
from stdnum.exceptions import *
47+
from stdnum.util import clean, isdigits
48+
49+
50+
def compact(number):
51+
"""Convert the number to the minimal representation. This strips the number
52+
of any valid separators and removes surrounding whitespace."""
53+
number = clean(number, ' -.').strip()
54+
return number
55+
56+
57+
def _checksum(number):
58+
"""Calculate the checksum."""
59+
numbers = [number]
60+
if int(number[:2]) + 2000 <= datetime.date.today().year:
61+
numbers.append('2' + number)
62+
for n in numbers:
63+
if 97 - (int(n[:-2]) % 97) == int(n[-2:]):
64+
return True
65+
return False
66+
67+
68+
def validate(number):
69+
"""Check if the number if a valid National Number."""
70+
number = compact(number)
71+
if not isdigits(number) or int(number) <= 0:
72+
raise InvalidFormat()
73+
if len(number) != 11:
74+
raise InvalidLength()
75+
if not _checksum(number):
76+
raise InvalidChecksum()
77+
return number
78+
79+
80+
def is_valid(number):
81+
"""Check if the number is a valid National Number."""
82+
try:
83+
return bool(validate(number))
84+
except ValidationError:
85+
return False
86+
87+
88+
def format(number):
89+
"""Reformat the number to the standard presentation format."""
90+
number = compact(number)
91+
return (
92+
'.'.join(number[i:i + 2] for i in range(0, 6, 2)) +
93+
'-' + '.'.join([number[6:9], number[9:11]]))

0 commit comments

Comments
 (0)
0