Regex Indian Aadhaar number
An Aadhaar number has 12 digits, usually written as three groups of 4 separated by spaces ('2341 2341 2346'). The last digit is a check digit computed with the Verhoeff algorithm. The UIDAI design paper of 2010 (a proposal, not a regulation) reserves a first digit of 0 for future extension and 1 for entities, and plans numbers from 2 to 9 for individuals; python-stdnum applies the same bound. Among the patterns read here, validator.js still accepts a leading '1', django-localflavor also accepts 0 and the hyphen, and the two Presidio patterns, built for detection, are not anchored. Here's a pattern bounding the first digit and requiring the same separator between groups, compared against those attempts.
/^[2-9][0-9]{3}( ?)[0-9]{4}\1[0-9]{4}$/passes 23/23 cases
Comparison of existing patterns
| Source | pattern | Score on the corpus | ReDoS |
|---|---|---|---|
| validator.js isIdentityCard('IN') — ancrée, mais « [1-9] » laisse passer un 1 en tête (« 123412341234 ») et chaque « \s? » est indépendant : « 2341 23412346 » passe | ^[1-9]\d{3}\s?\d{4}\s?\d{4}$ | 21 / 23 | safe |
| django-localflavor (in_/forms.py) — accepte 0 ou 1 en tête, le tiret et des séparateurs mixtes (« 2341-2341 2346 ») ; groupes nommés convertis en syntaxe JS | ^(?<part1>\d{4})[-\ ]?(?<part2>\d{4})[-\ ]?(?<part3>\d{4})$ | 19 / 23 | safe |
| Presidio, motif « AADHAAR (Very Weak) » — détection non ancrée par \b : « id=234123412346; » et « 123412341234 » passent, la forme avec espaces est refusée | \b[0-9]{12}\b | 16 / 23 | safe |
| Presidio, motif « AADHAR (Very Weak) » — séparateur « [- :] » (deux-points accepté), 1 en tête accepté, non ancré | \b[0-9]{4}[- :][0-9]{4}[- :][0-9]{4}\b | 15 / 23 | safe |
| python-stdnum (in_/aadhaar.py) — borne 2-9 correcte, mais appliquée après nettoyage des séparateurs : le motif seul refuse « 2341 2341 2346 » | ^[2-9][0-9]{11}$ | 20 / 23 | safe |
Implementation
const re = new RegExp("^[2-9][0-9]{3}( ?)[0-9]{4}\\1[0-9]{4}$", "");
re.test(input);Limits
- Valide seulement la FORME : ne calcule pas la clé Verhoeff. « 234123412347 » a la bonne forme mais une clé fausse et passe ce motif ; le test Verhoeff se fait dans le code, pas dans une regex.
- La borne « premier chiffre de 2 à 9 » vient d'un document de conception de l'UIDAI (2010) et de python-stdnum, pas d'un texte réglementaire que j'ai pu ouvrir. Les numéros palindromes (« 222222222222 »), que python-stdnum rejette, passent aussi.
- Seul l'espace sert de séparateur (celui de l'écriture habituelle par groupes de 4) : le tiret accepté par django-localflavor et le deux-points de Presidio sont refusés ; normalisez avant validation.
- N'établit pas qu'un numéro a été attribué. Le numéro est une donnée personnelle sensible en Inde : n'utilisez dans vos tests que des numéros synthétiques à clé valide comme ceux du corpus.