Regex Bulgarian EGN (unified civil number)
The EGN has 10 digits: the year on 2 digits, the month, the day, 3 serial digits whose parity gives the sex, and a modulo 11 key. The century is encoded in the month: 01-12 for births from 1900 to 1999, 21-32 for before 1900 (+20) and 41-52 for after 1999 (+40) (DG TAXUD specification). The three real attempts I read accept '10 digits' with no date check: '9913999999' (month 13, day 99) passes. Here's a pattern bounding the encoded month and the day, compared against those attempts. The key (weights 2, 4, 8, 5, 10, 9, 7, 3, 6, modulo 11) and the real date are left to code.
/^\d{2}(?:0[1-9]|1[0-2]|2[1-9]|3[0-2]|4[1-9]|5[0-2])(?:0[1-9]|[12]\d|3[01])\d{4}$/passes 25/25 cases
Comparison of existing patterns
| Source | pattern | Score on the corpus | ReDoS |
|---|---|---|---|
| validator.js isTaxID (bg-BG) — ancrée mais « \d{10} » seulement : « 9913999999 » (mois 13, jour 99) passe | ^\d{10}$ | 18 / 25 | safe |
| piigex (détecteur bg_egn) — lookarounds seulement, sans borne de date : « x-7501010010 » passe, ainsi que « 0000000000 » | (?<!\d)\d{10}(?!\d) | 17 / 25 | safe |
| OpenRedaction (BULGARIAN_PERSONAL_NUMBER, regex de détection) — \b…\b non ancré, 10 chiffres quelconques : « EGN 7501010010 » passe ; la date est vérifiée dans un validateur à part | \b(\d{10})\b | 17 / 25 | safe |
Implementation
const re = new RegExp("^\\d{2}(?:0[1-9]|1[0-2]|2[1-9]|3[0-2]|4[1-9]|5[0-2])(?:0[1-9]|[12]\\d|3[01])\\d{4}$", "");
re.test(input);Limits
- Valide la forme (mois codé 01-12, 21-32, 41-52, jour 01-31) mais PAS la clé : « 7501010011 » passe. Complément : clé = (Σ chiffre[i] × poids[i] pour les 9 premiers, poids 2, 4, 8, 5, 10, 9, 7, 3, 6) % 11, ramené à 0 si 10.
- Le jour 31 est accepté pour tous les mois (« 9904311… » = 31 avril passe) et la date n'est pas confrontée à aujourd'hui : l'EGN d'un enfant « né en 2099 » est accepté. Calculez la date réelle à partir du mois codé pour la contrôler.
- Le siècle est ambigu sans le mois codé : le motif accepte l'ensemble 1800-2099. Aucune vérification d'attribution ; l'EGN est une donnée personnelle, n'utilisez que l'exemple officiel ou des numéros synthétiques à date future.