Rexact
Cheatsheet

Regex South African ID number

A South African ID number has 13 digits: YYMMDD, 4 serial digits (gender), a citizenship digit, a 12th digit and a Luhn check. The 12th digit is normally 8, and 9 when the day's series runs out, per a 2000 regulatory amendment: a Microsoft Q&A regex forces it to 8 and so rejects valid numbers. The citizenship rule is also poorly handled: 0 or 1 in the regulation text, 2 for refugees in libraries. Here's a pattern bounding months and days, accepting 0 to 2 for citizenship and not forcing the 12th digit, compared against those attempts.

/^[0-9]{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12][0-9]|3[01])[0-9]{4}[0-2][0-9][0-9]$/
passes 22/22 cases

Comparison of existing patterns

Implementation

const re = new RegExp("^[0-9]{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12][0-9]|3[01])[0-9]{4}[0-2][0-9][0-9]$", "");
re.test(input);

Limits

  • Valide seulement la FORME : ne calcule pas la clé Luhn (13e chiffre), ne vérifie pas le jour dans le mois ni les années bissextiles (« 0002305009082 », un 30 février, passe), et ne connaît pas le siècle : AAMMJJ est ambigu (« 0402290001187 » est valide comme 29 février 2004, pas comme 1904).
  • Le 12e chiffre vaut normalement 8, et 9 quand la série du jour est épuisée (amendement de 2000). Les anciens numéros peuvent porter d'autres valeurs : le motif accepte n'importe quel chiffre pour ne pas rejeter de numéros valides, au prix de ne pas contrôler cette position.
  • La citoyenneté 0 ou 1 vient du texte réglementaire (copie secondaire consultée, la Gazette étant protégée) ; 2 (réfugié) vient de Wikipédia et de bibliothèques tierces. Le motif accepte 0 à 2 : si vous suivez strictement le texte de 1998, restreignez à [01].
  • Les numéros du corpus sont synthétiques, avec une clé Luhn recalculée : aucun jeu d'exemples officiel n'existe. N'utilisez jamais de vrais numéros d'identité dans vos tests. L'existence réelle d'un numéro ne peut être confirmée que par le Département des Affaires intérieures.

Related pages