Numéro national belge

Définition

Le numéro de registre national ou numéro d’identification du registre national ou numéro national (N.N.) en Belgique est un identifiant unique et personnel composé de 11 chiffres. Ce numéro est repris sur la carte d’identité belge.



Détail

Les 6 premières positions forment la date de naissance sous la forme AA/MM/JJ (année, mois, jour). Par exemple, pour une personne née le 30 juillet 1985, les 6 premiers chiffres de son numéro national sont donc 85.07.30. Lorsque la date de naissance est incomplète, par exemple pour les personnes qui ne sont pas en mesure de prouver par un acte leur date de naissance complète au niveau de l’administration communale et du registre national, les deux premiers chiffres indiquent l’année de naissance, les troisième, quatrième, cinquième et sixième chiffres sont représentés par le chiffre zéro (exemple : 40 00 00 955-79). Lorsque la date de naissance est inconnue, les cinq premiers chiffres de la date de naissance sont représentés par le chiffre zéro et le sixième chiffre est un (exemple : 00 00 01 003-64).

Les 3 positions suivantes constituent le compteur journalier des naissances. Il existe un compteur journalier par sexe, ce nombre étant pair pour les femmes et impair pour les hommes. Lorsque la date de naissance est incomplète, le numéro d’ordre est constitué par le rang d’inscription de la personne dans l’année de naissance, lorsque, dans ce cas, tous les numéros de série ont été utilisés (de 001 à 997 pour les hommes, par exemple), l’ordinateur utilise comme premier groupe un jour de naissance égal à 01 et recommence le radical à 001 (exemple : 40 00 01 001-33).

Les 2 dernières positions constituent le chiffre de contrôle. Ce chiffre de contrôle est une suite de 2 chiffres formant un nombre compris entre 01 et 97. Ce nombre est égal à 97 moins le reste de la division par 97 du nombre formé (modulo de 97)(le reste de la division est un chiffre non divisible par 97, et donc inférieur à 97 dans ce cas. Par exemple pour 98 cela serait 1, pour 99 cela serait 2, pour 100 cela serait 3 ou pour 195 cela serait 1) :

  • soit par les 9 premiers chiffres du numéro national pour les personnes nées avant le 1er janvier 2000 ;
    • ex : 850730 033 donne 97 – (850730033 mod 97) = 97 – 69 = 28 donc le numéro national est 85 07 30 033 28
  • soit par le chiffre 2 suivi des 9 premiers chiffres du numéro national pour les personnes nées après le 31 décembre 1999.
    • ex : 170730 033 donne 97 – (2170730033 mod 97) = 97 – 13 = 84 donc le numéro national est 17 07 30 033 84

🇧🇪 Qu’est-ce qu’un numéro de registre national belge ?

Il a la forme suivante :

YYMMDD-XXX-CC

YYMMDD : date de naissance (2 chiffres pour l’année)

XXX : un numéro de série (généralement impair pour les hommes, pair pour les femmes)

CC : une clé de contrôle (checksum) calculée sur les 9 premiers chiffres

✅ Comment fonctionne le checksum belge ?

Voici la règle officielle :

La clé de contrôle CC = 97 – (numéro à 9 chiffres modulo 97)

⚠️ Si la personne est née après l’an 2000, on ajoute 2000000000 au numéro avant de faire le modulo.


📘 Exemple :

Numéro : 970625-123-85
→ On enlève les tirets : 970625123

970625123 % 97 = 12
97 - 12 = 85 ✅ La clé 85 correspond → numéro valide

🧠 Étapes en Python :

  1. Extraire les 11 chiffres
  2. Tester le format YYMMDDXXXCC
  3. Calculer la clé en tenant compte de l’année (>2000 ?)
  4. Vérifier si le résultat = les 2 derniers chiffres

import re

def verifier_numero_registre(nrn):
    # Vérifie le format de base
    if not re.match(r'^\d{6}-\d{3}-\d{2}$', nrn):
        return False

    # Enlever les tirets
    parties = nrn.replace('-', '')

    base = parties[:9]       # les 9 premiers chiffres
    cle = int(parties[9:])   # les 2 derniers chiffres (checksum)

    # Vérification pré-2000
    calc1 = 97 - (int(base) % 97)
    # Vérification post-2000
    calc2 = 97 - ((2000000000 + int(base)) % 97)

    # Si une des deux clés correspond → valide
    return cle == calc1 or cle == calc2

# 🔍 Exemple de test
n1 = "970625-123-85"  # ✅ valide (né avant 2000)
n2 = "010101-001-75"  # ✅ valide (né après 2000)
n3 = "010101-001-12"  # ❌ invalide

for n in [n1, n2, n3]:
    print(f"{n} → {'✅ Valide' if verifier_numero_registre(n) else '❌ Invalide'}")

Générateur d’un numéro national bidon selon sexe et année de naissance

En python

import random
from datetime import datetime

def generer_nrn(sexe: str, naissance: int) -> str:
    """
    Génère un numéro de registre national belge valide.
    
    :param sexe: 'homme' ou 'femme'
    :param naissance: année de naissance (ex: 1985)
    :return: chaîne de caractères au format YYMMDD-XXX-CC
    """

    # 1. Générer une date de naissance aléatoire dans l'année
    mois = random.randint(1, 12)
    jour = random.randint(1, 28 if mois == 2 else 30 if mois in [4, 6, 9, 11] else 31)

    date_naissance = datetime(naissance, mois, jour)
    date_str = date_naissance.strftime('%y%m%d')  # format YYMMDD

    # 2. Générer un numéro de série (XXX)
    base_num = random.randint(1, 997)
    if sexe.lower() == 'femme':
        if base_num % 2 != 0:
            base_num += 1  # rendre pair
    elif sexe.lower() == 'homme':
        if base_num % 2 == 0:
            base_num += 1  # rendre impair
    else:
        raise ValueError("Sexe doit être 'homme' ou 'femme'.")

    xxx = f"{base_num:03d}"  # zero-padded

    # 3. Calculer la clé de contrôle (CC)
    num_sans_cle = f"{date_str}{xxx}"
    base_int = int(num_sans_cle)

    if naissance >= 2000:
        base_int = 2000000000 + base_int

    cle = 97 - (base_int % 97)
    cc = f"{cle:02d}"

    # 4. Formater le tout
    return f"{date_str}-{xxx}-{cc}"

# 🧪 Exemple d'utilisation
if __name__ == "__main__":
    sexe = "femme"
    annee_naissance = 2001

    numero = generer_nrn(sexe, annee_naissance)
    print(f"🎉 Numéro généré : {numero}")

En ASP

Dédicace spécial à mon ancien collègue Guillaume de chez Zenith …

<%
Randomize

Function ZeroPad(number, length)
    Dim str : str = CStr(number)
    Do While Len(str) < length
        str = "0" & str
    Loop
    ZeroPad = str
End Function

Function GenererNRN(sexe, annee)
    ' 1. Générer une date de naissance
    mois = Int((12 * Rnd) + 1)
    If mois = 2 Then
        jour = Int((28 * Rnd) + 1)
    ElseIf mois = 4 Or mois = 6 Or mois = 9 Or mois = 11 Then
        jour = Int((30 * Rnd) + 1)
    Else
        jour = Int((31 * Rnd) + 1)
    End If

    dateStr = Right("0" & (annee Mod 100), 2) & Right("0" & mois, 2) & Right("0" & jour, 2)

    ' 2. Numéro de série
    baseNum = Int((997 * Rnd) + 1)
    If LCase(sexe) = "femme" Then
        If baseNum Mod 2 <> 0 Then baseNum = baseNum + 1
    ElseIf LCase(sexe) = "homme" Then
        If baseNum Mod 2 = 0 Then baseNum = baseNum + 1
    Else
        GenererNRN = "Erreur : sexe inconnu"
        Exit Function
    End If
    xxx = ZeroPad(baseNum, 3)

    ' 3. Calcul de la clé
    numSansCle = dateStr & xxx
    If annee >= 2000 Then
        base = CLng("2000000000") + CLng(numSansCle)
    Else
        base = CLng(numSansCle)
    End If

    cle = 97 - (base Mod 97)
    cc = ZeroPad(cle, 2)

    ' 4. Format final
    GenererNRN = Mid(dateStr, 1, 6) & "-" & xxx & "-" & cc
End Function

' 🧪 Exemple
sexe = "femme"
annee = 2003

nrn = GenererNRN(sexe, annee)
Response.Write "<h3>🎉 Numéro national généré : " & nrn & "</h3>"
%>

Notes :

  • Pas de DateSerial natif, on génère manuellement le jour/mois/année.
  • En ASP classique, le typage est flou (Variant) donc prudence avec les opérations arithmétiques.
  • Randomize + Rnd pour les valeurs aléatoires.
  • ZeroPad est une fonction custom (pas de Format()).

En PHP

<?php

function zeroPad($nombre, $taille) {
    return str_pad($nombre, $taille, "0", STR_PAD_LEFT);
}

function generer_nrn($sexe, $annee) {
    // 1. Générer une date aléatoire valide
    $mois = rand(1, 12);
    $jour = rand(1, cal_days_in_month(CAL_GREGORIAN, $mois, $annee));

    $yy = substr($annee, -2);
    $date_str = zeroPad($yy, 2) . zeroPad($mois, 2) . zeroPad($jour, 2);

    // 2. Numéro de série
    $numero = rand(1, 997);
    if ($sexe === "femme" && $numero % 2 !== 0) $numero++;
    if ($sexe === "homme" && $numero % 2 === 0) $numero++;
    $xxx = zeroPad($numero, 3);

    // 3. Calcul de la clé
    $num9 = $date_str . $xxx;
    $base = ($annee >= 2000) ? (2000000000 + intval($num9)) : intval($num9);
    $cle = 97 - ($base % 97);
    $cc = zeroPad($cle, 2);

    // 4. Format final
    return substr($date_str, 0, 6) . "-" . $xxx . "-" . $cc;
}

// 🧪 Exemple d'utilisation
$sexe = "femme";
$annee = 2003;
$nrn = generer_nrn($sexe, $annee);

echo "<h3>🎉 Numéro national généré : $nrn</h3>";
?>

Ce code fonctionne en :

  • PHP 5.x → 8.x
  • Sans bibliothèque externe
  • Sans MySQL, ni framework
  • Brut, rapide, propre