Regex numéro CPR danois
Un CPR s'écrit « 070761-4285 » : JJMMAA, un tiret facultatif et 4 chiffres. Le siècle est déduit du 7e chiffre et de l'année par une table officielle. Ancienne règle : la somme pondérée (4,3,2,7,6,5,4,3,2,1) devait être divisible par 11. Mais le CPR-kontor écrit sur son site que depuis 2007 il attribue des numéros « uden såkaldt modulus 11 kontrol », qui sont « fuldt ud gyldige personnumre » : les systèmes doivent les accepter. La bibliothèque angular-cpr-validator exige pourtant le modulo 11 par défaut et les rejette, un gist exige le tiret, et celle d'OS2datascanner, conçue pour détecter, accepte « 320131-4006 ». Voici un motif qui borne mois et jours sans exiger la clé, comparé à ces tentatives.
/^(?:0[1-9]|[12][0-9]|3[01])(?:0[1-9]|1[0-2])[0-9]{2}-?[0-9]{4}$/passe 24/24 cas
Comparatif des patterns existants
| Source | pattern | Score sur le corpus | ReDoS |
|---|---|---|---|
| Gist sstarr (cpr.rb, 2013) — tiret obligatoire : rejette « 0707614285 », la forme sans tiret très courante ; « 300232-4006 » (30 février) passe ; \b non ancrée | \b(0[1-9]|[12]\d|3[01])(0[1-9]|1[0-2])\d{2}-\d{4}\b | 23 / 24 | sûr |
| OS2datascanner (scanner open source du secteur public) — conçue pour détecter, tolère espaces, points, barres, tabulations ; aucune contrainte de date : « 320131-4006 », « 001231-4006 » et « 011331-4006 » passent ; non ancrée | \b(\d{2}[ ]?\d{2}[ ]?\d{2})(?:[ \-/\.\t]|[ ]\-[ ])?(\d{4})\b | 19 / 24 | sûr |
| angular-cpr-validator (npm) — « ^\d{10}$ » (après retrait du tiret) : « 9999999999 » passe ; sa vérification modulo 11, activée par défaut dans le code, rejette ensuite les numéros valides attribués depuis 2007 | ^\d{10}$ | 14 / 24 | sûr |
Implémentation
const re = new RegExp("^(?:0[1-9]|[12][0-9]|3[01])(?:0[1-9]|1[0-2])[0-9]{2}-?[0-9]{4}$", "");
re.test(input);Limites
- Valide seulement la FORME : ne vérifie ni le modulo 11 (qui n'est plus une condition de validité depuis 2007 d'après le CPR-kontor), ni le nombre de jours du mois (« 300232-4006 », 30 février, passe), ni les années bissextiles : « 290201-4123 » (2001) passe. Le siècle découle d'une table officielle (7e chiffre et année) que ce motif ne reprend pas : « 290200-0123 » (1900, non bissextile) passe aussi.
- Le contrôle modulo 11 reste utile comme indice, mais plus comme test de validité : les numéros sans clé sont attribués pour certaines générations parce que les numéros avec clé s'épuisent. Beaucoup de bibliothèques l'imposent encore (angular-cpr-validator, danish-ssn).
- Tout CPR bien formé peut appartenir à une personne réelle : n'utilisez que le numéro d'exemple du document du CPR-kontor (070761-4285) ou des numéros dont la date de naissance est dans le futur, comme ceux du corpus. Les jeux de données de test officiels (Fællesoffentlige Testdatasæt) ne sont pas listés publiquement.
- Le tiret est facultatif. Les espaces, points et barres tolérés par certains détecteurs sont rejetés : normalisez avant validation. Le motif ne distingue pas un numéro attribué d'un numéro non attribué.