Het Belgisch Rijksregister1 is een databank met gegevens over elke inwoner van België. De databank wordt beheerd door de Federale Overheidsdienst Binnenlandse Zaken2, maar de gegevens worden aangeleverd door de dienst Bevolking van de gemeenten. Kort na de geboorte krijgt elke inwoner een uniek rijksregisternummer3 waarmee een aantal administratieve gegevens in het Rijksregister terug te vinden zijn (domicilie, burgerlijke stand, nationaliteit). Dit nummer staat vermeld op de identiteitskaart en kan persoonlijk opgevraagd worden aan het loket van de dienst Bevolking.

Belgische identiteitskaart
Identiteitskaart van België waarop het rijksregisternummer wordt aangeduid met een rode pijl.

Het rijksregisternummer bestaat uit 11 cijfers:

Op die manier weten we bijvoorbeeld dat het rijksregisternummer 93051822361 toegekend werd aan een man (oneven dagteller) die geboren is op 18 mei 1993 (eerste groep). We kunnen afleiden dat het geboortejaar 1993 is en niet 2093 (mochten we al zover zijn) omdat de deling van 930518223 door 97 rest 36 oplevert. We krijgen dan dat 97 - 36 gelijk is aan het controlegetal 61. Als de inwoner geboren was in 2093 dan zouden we voor de berekening van het controlegetal 2930518223 delen door 97 om rest 7 te bekomen. In dat geval had het controlegetal 97 - 7 = 90 moeten zijn.

Opgave

Definieer een klasse Rijksregisternummer waarmee de geldigheid van rijkregisternummers kan gecontroleerd worden. Bij het aanmaken van objecten van de klasse Rijksregisternummer moet een string doorgegeven worden. Als het argument dat wordt doorgegeven geen string is dan moet een AssertionError opgeworpen worden met de boodschap ongeldig type. Bovendien moet de gegeven string exact 11 cijfers bevatten (alle karakters die geen cijfer zijn worden genereerd). Als dat niet het geval is dan moet een AssertionError opgeworpen worden met de boodschap ongeldig formaat (n cijfers). Hierbij is $$n$$ het aantal cijfers in de gegeven string. Als $$n = 1$$ dan moet de boodschap de enkelvoudsvorm (1 cijfer) gebruiken.

Zorg ervoor dat de ingebouwde functie repr een stringvoorstelling van een rijksregisternummer (object van de klasse Rijksregisternummer) teruggeeft in het formaat

Rijksregisternummer('nummer')

Daarbij correspondeert nummer met de cijfers van de string die werd doorgegeven bij het aanmaken van het object. Alle karakters die geen cijfer zijn, moeten daarin dus geschrapt worden.

Zorg er ook voor dat de ingebouwde functie str een stringvoorstelling van een rijksregisternummer (object van de klasse Rijksregisternummer) teruggeeft in het formaat

jj.mm.dd-xxx.cc

Daarbij corresponderen de cijfers jj, mm en dd met de geboortedatum (respectievelijk jaar, dag en maand), xxx met de dagteller en cc met het controlegetal.

De klasse Rijksregisternummer moet minstens de volgende methoden ondersteunen:

Voorbeeld

# geboren voor 2000
>>> rrn = Rijksregisternummer('75.12.05-137.14')
>>> rrn
Rijksregisternummer('75120513714')
>>> print(rrn)
75.12.05-137.14
>>> rrn.controlegetal()
14
>>> rrn.controlegetal(y2k=True)
43
>>> rrn.geboortedatum()
datetime.date(1975, 12, 5)
>>> rrn.geslacht()
'man'
>>> rrn.geldig()
True

# geboren na 2000
>>> rrn = Rijksregisternummer('>>>09082428248<<<LENA<NADINE<INGRID')
>>> rrn
Rijksregisternummer('09082428248')
>>> print(rrn)
09.08.24-282.48
>>> rrn.controlegetal(y2k=False)
19
>>> rrn.controlegetal(y2k=True)
48
>>> rrn.geboortedatum()
datetime.date(2009, 8, 24)
>>> rrn.geslacht()
'vrouw'
>>> rrn.geldig()
True

# ongeldige rijkregisternummers
>>> Rijksregisternummer(1234567890)
Traceback (most recent call last):
AssertionError: ongeldig type
>>> Rijksregisternummer('xxx3xxx')
Traceback (most recent call last):
AssertionError: ongeldig formaat (1 cijfer)
>>> Rijksregisternummer('1234567890')
Traceback (most recent call last):
AssertionError: ongeldig formaat (10 cijfers)
>>> Rijksregisternummer('12.34.56-789.10').geboortedatum()
Traceback (most recent call last):
AssertionError: ongeldige geboortedatum
>>> Rijksregisternummer('12.34.56-789.10').geldig()
False
>>> Rijksregisternummer('85.02.01-002.00').geboortedatum()
datetime.date(1985, 2, 1)
>>> Rijksregisternummer('85.02.01-002.00').geldig()
False

Epiloog

Omdat het rijksregisternummer enkel gebruikmaakt van de laatste twee cijfers van het geboortejaar, bestond de kans dat rijkregisternummers na het jaar 2000 niet langer uniek zouden zijn. Om deze manifestering van de milleniumbug4 (aka Y2K) het hoofd te bieden, werd op 25 november 1997 per koninklijk besluit vastgelegd dat vanaf de overgang naar het jaar 2000 bij de berekening van het controlegetal een extra cijfer 2 moest toegevoegd worden vóór de aaneenschakeling van de negen cijfers van de geboortedatum en de dagteller.

Over een paar decennia dreigt een gelijkaardige crisis met de social security numbers5 die in de Verenigde Staten gebruikt worden om inwoners te identificeren. Ook die identificatienummers zijn uniek en worden nooit gerecycleerd als iemand sterft. Er zijn ongeveer één miljard verschillende identificatienummers en sinds 1936 werd daarvan ongeveer al één derde toegekend. Volgens sommige schattingen zouden de beschikbare identificatienummers tegen 2075 allemaal opgebruikt zijn.

Wat zal er dan gebeuren? Wie zal het zeggen? Maar als de regering daardoor valt dan kunnen de Amerikanen altijd nog naar Zuid-Amerika trekken: daar geven de nationale identificatienummers toegang tot online videogames.