The National Register of Belgium1 is a database containing information about all residents of Belgium. The database is managed by the Federal Public Service Interior2, but the data is supplied by the Population Service of the individual municipalities. Shortly after birth, each resident receives a unique national register number3 that can be used to find administrative information in the National Register (domicile, civil status, nationality). This number is indicated on the ID card and can be personally requested at the counter of the Population Service.

Belgian ID card
Belgian ID card where the national register number is marked with a red arrow.

The national register number consists of 11 digits:

This information tells us for example that the national register number 93051822361 was assigned to a male resident (odd daily serial number) who was born on May 18, 1993 (first group). We can infer that the year of birth is 1993 and not 2093 (if we would already have reached that year) because the remainder after integer division of 930518223 by 97 is 36. We then get that 97 - 36 is equal to the check number 61. If the resident was born in 2093, we would compute the check number as the division of 2930518223 by 97 to get 7 as a remainder. In that case the check number should have been 97 - 7 = 90.

Assignment

Define a class NationalRegisterNumber that can be used to check the validty of Belgian national register numbers. A string must be passed when creating objects of the class NationalRegisterNumber. If the given argument is not a string, an AssertionError must be raised with the message invalid type. In addition, the given string must contain exactly 11 digits (all characters that are no digits are ignored). If this is not the case, an AssertionError must be raised with the message invalid format (n digits), with $$n$$ being the number of digits in the given string. The message must use the singular form (1 digit) if $$n = 1$$.

Make sure that the built-in function repr returns a string representation for national register numbers (objects of the class NationalRegisterNumber) in the format

NationalRegisterNumber('number')

where number corresponds to the digits in the string that was passed when creating the object. All characters that are not digits must therefore be deleted.

Also make sure that the built-in function str returns a string representation for national register numbers (objects of the class NationalRegisterNumber) in the format

yy.mm.dd-xxx.cc

where the digits yy, mm and dd corrrespond to the date of birth (respectively year, month and day), xxx with the daily serial number and cc with the check number.

The class NationalRegisterNumber must support at least the following methods:

Example

# born before the year 2000
>>> nrn = NationalRegisterNumber('75.12.05-137.14')
>>> nrn
NationalRegisterNumber('75120513714')
>>> print(nrn)
75.12.05-137.14
>>> nrn.checksum()
14
>>> nrn.checksum(y2k=True)
43
>>> nrn.birthday()
datetime.date(1975, 12, 5)
>>> nrn.gender()
'male'
>>> nrn.valid()
True

# born since the year 2000
>>> nrn = NationalRegisterNumber('>>>09082428248<<<LENA<NADINE<INGRID')
>>> nrn
NationalRegisterNumber('09082428248')
>>> print(nrn)
09.08.24-282.48
>>> nrn.checksum(y2k=False)
19
>>> nrn.checksum(y2k=True)
48
>>> nrn.birthday()
datetime.date(2009, 8, 24)
>>> nrn.gender()
'female'
>>> nrn.valid()
True

# invalid identification numbers
>>> NationalRegisterNumber(1234567890)
Traceback (most recent call last):
AssertionError: invalid type
>>> NationalRegisterNumber('xxx3xxx')
Traceback (most recent call last):
AssertionError: invalid format (1 digit)
>>> NationalRegisterNumber('1234567890')
Traceback (most recent call last):
AssertionError: invalid format (10 digits)
>>> NationalRegisterNumber('12.34.56-789.10').birthday()
Traceback (most recent call last):
AssertionError: invalid birthday
>>> NationalRegisterNumber('12.34.56-789.10').valid()
False
>>> NationalRegisterNumber('85.02.01-002.00').birthday()
datetime.date(1985, 2, 1)
>>> NationalRegisterNumber('85.02.01-002.00').valid()
False

Epilogue

Because the national register number of Belgium only uses the last two digits of the year of birth, there was a chance that national register numbers would no longer be unique after the year 2000. In order to cope with this manifestation of the Millenium bug4 (aka Y2K), it was established on November 1997 by royal decree that in the computation of the check number an additional digit 2 must be prepended to the sequence of the first nine digits of the date of birth and the daily serial number for residents born from the year 2000 onward.

In a few decades a similar crisis threatens the Social Security Number5 that the United States uses to identify its residents. These numbers are also unique and are never recycled when somebody dies. About a billion numbers are possible. The United States started to assign these numbers in 1936 and already about a third of the possibilities have been used up since. According to some estimates they could run out by 2075.

What happens then? Who knows? But if the American government collapses, its residents could head to South Korea: their social security numbers give access to online video games.