Regex UnionPay card number
China UnionPay numbers start with 62 and have 16 to 19 digits (Wikipedia's table; the 2017 Discover bulletin lists sub-ranges 622126-622925, 624-626 and 6282-6288 with the same length). The attempts I read disagree: validator.js fixes 16 digits for '62' but also accepts '67' (a Maestro prefix) and an '81' prefix of 16 to 19 digits, Cleave.js only tests the prefix (62 or 81), php-credit-card-validator tests '62' or '88' with no length. Here's a pattern on prefix 62 with 16 to 19 digits, compared against those attempts.
/^62[0-9]{14,17}$/passes 23/23 cases
Comparison of existing patterns
| Source | pattern | Score on the corpus | ReDoS |
|---|---|---|---|
| validator.js (isCreditCard) — 62 ou 67 sur 16 chiffres (67 est un préfixe Maestro) ; 17 à 19 chiffres refusés pour 62 ; accepte un préfixe 81 | ^(6[27][0-9]{14}|^(81[0-9]{14,17}))$ | 19 / 23 | safe |
| Cleave.js — motif de saisie progressive sans ancre de fin : « 62 » seul, 20 chiffres et plus passent ; préfixe 81 accepté | ^(62|81)\d{0,14} | 17 / 23 | safe |
| php-credit-card-validator — « 62 » ou « 88 » sans longueur : toute longueur passe | ^(62|88) | 17 / 23 | safe |
Implementation
const re = new RegExp("^62[0-9]{14,17}$", "");
re.test(input);Limits
- Valide seulement la FORME (préfixe et longueur) : ni la clé de Luhn (le corpus contient un numéro de forme correcte et de clé fausse qui passe), ni l'existence du compte, ni la date d'expiration ou le CVV. Les espaces et tirets sont refusés : normalisez avant validation.
- Sources secondaires pour le préfixe 62 et la longueur 16-19 (voir commentaire). Certaines cartes UnionPay anciennes ne respectent pas la clé de Luhn selon des sources non vérifiées ici : ne rejetez pas sur la seule clé sans consulter votre acquéreur.
- Le préfixe 62 englobe des co-marques (Discover 622126-622925) ; le motif ne les distingue pas.
- Ne stockez ni ne journalisez de vrais numéros de carte (PCI DSS) ; n'utilisez que des numéros de test dans vos tests.