Regex Estonian personal code (isikukood)
The isikukood has 11 digits: a century and sex digit (1 to 6), the year on 2 digits, the month (01-12), the day (01-31), a serial number (001 to 710 per the DG TAXUD specification) and a modulo 11 key with two weight sets (1 to 9 then 1, and 3 to 9 then 1, 2, 3 if the first remainder is 10). The three real attempts I read lack some of these bounds: one accepts bare digits without checking month or day, another is unanchored, and a third checks the serial but accepts '39913330010' (month 13, day 33). Here's a pattern bounding century, month, day and serial, compared against those attempts. The key and the existence of the day (February 31) are left to code.
/^[1-6]\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01])(?:00[1-9]|0[1-9]\d|[1-6]\d{2}|70\d|710)\d$/passes 24/24 cases
Comparison of existing patterns
| Source | pattern | Score on the corpus | ReDoS |
|---|---|---|---|
| validator.js isTaxID (et-EE) — borne le siècle et la série 001-710 mais pas le mois ni le jour : « 39913330010 » (mois 13, jour 33) passe | ^[1-6]\d{6}(00[1-9]|0[1-9][0-9]|[1-6][0-9]{2}|70[0-9]|710)\d$ | 21 / 24 | safe |
| django-localflavor (EEPersonalIdentificationCode) — ancrée, siècle 1-6, mais mois, jour et série libres : « 39913330010 » et « 30001010000 » passent | ^([1-6])(\d\d)(\d\d)(\d\d)(?:\d{3})(\d)$ | 19 / 24 | safe |
| piigex (détecteur ee_ik) — siècle 1-6 seulement ; lookarounds sans ancres de chaîne (« x-37102250382 » passe), ni mois, ni jour, ni série | (?<!\d)[1-6]\d{10}(?!\d) | 18 / 24 | safe |
Implementation
const re = new RegExp("^[1-6]\\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\\d|3[01])(?:00[1-9]|0[1-9]\\d|[1-6]\\d{2}|70\\d|710)\\d$", "");
re.test(input);Limits
- Valide la forme (siècle, mois, jour, série) mais PAS la clé modulo 11 : « 37102250383 » passe. Complément : s1 = Σ chiffre[i] × ((i % 9) + 1) pour les 10 premiers chiffres, modulo 11 ; si s1 vaut 10, s2 = Σ chiffre[i] × (((i + 2) % 9) + 1) modulo 11 ; la clé est s % 10.
- Le jour 31 est accepté pour tous les mois et le 29 février pour toute année : « 59902 31123… » (31 février) passe ; calculez la date à partir du siècle, de l'année, du mois et du jour pour la vérifier.
- Les chiffres 7 et 8 (siècle 2100, accepté par python-stdnum) sont refusés comme dans la spécification DG TAXUD ; la série est bornée à 001-710 d'après cette spécification, mais d'autres systèmes peuvent émettre au-delà (le code personnel lituanien partage la structure sans cette borne : voir la fiche asmens-kodas-lituanien). Aucune vérification d'existence.
- Un isikukood est une donnée personnelle : n'utilisez que les exemples du document officiel ou des numéros synthétiques à date de naissance future, comme ceux du corpus.