Regex GSTIN indien (numéro de TVA)
Un GSTIN a 15 caractères : 2 chiffres de code d'État, les 10 caractères du PAN du contribuable, un compteur d'entité (1 à 9 puis A à Z), un « Z » et une clé modulo 36. Le code d'État va de 01 à 38 (la liste de la Zoho, source tierce, ajoute 97) ; le 4e caractère du PAN est le type de titulaire, une lettre parmi A B C F G H J L P T (page TRACES de l'administration fiscale). Les trois tentatives réelles que j'ai relues acceptent presque tout couple de chiffres en tête : « 00AAAPL1234C1ZU » et « 39AAAPL1234C1Z9 » passent, ainsi que « 27AAADE1234C1ZA », dont le type de titulaire « D » n'existe pas. L'une est même reprise telle quelle d'un README, sans ancres. Voici un motif qui borne code d'État et type de PAN, comparé à ces tentatives.
/^(?:0[1-9]|[12][0-9]|3[0-8]|97)[A-Z]{3}[ABCFGHJLPT][A-Z][0-9]{4}[A-Z][1-9A-Z]Z[0-9A-Z]$/passe 22/22 cas
Comparatif des patterns existants
| Source | pattern | Score sur le corpus | ReDoS |
|---|---|---|---|
| gstin-validator (npm) — ancrée, code d'État jusqu'à 38 et type de PAN, mais « [0-2][0-9] » accepte 00, le type « K » (absent de la liste de l'administration) est accepté et « 0 » en 13e position aussi ; rejette 97 | ^([0-2][0-9]|[3][0-8])[A-Z]{3}[ABCFGHLJPTK][A-Z]\d{4}[A-Z][A-Z0-9][Z][A-Z0-9]$ | 19 / 22 | sûr |
| @ashwinbande/validators (npm) — ancrée mais « \d{2} » : n'importe quel code d'État (« 00 », « 39 ») ; aucun contrôle du type de PAN (« 27AAADE1234C1ZA » passe) | ^\d{2}[A-Z]{5}\d{4}[A-Z][A-Z\d][Z][A-Z\d]$ | 18 / 22 | sûr |
| tk120404/gst (README, même regex que la réponse à 58 votes de Stack Overflow) — pas d'ancres : « XX27AAAPL1234C1ZE99 » passe ; aucun code d'État ni type de PAN contrôlé | \d{2}[A-Z]{5}\d{4}[A-Z]{1}[A-Z\d]{1}[Z]{1}[A-Z\d]{1} | 16 / 22 | sûr |
Implémentation
const re = new RegExp("^(?:0[1-9]|[12][0-9]|3[0-8]|97)[A-Z]{3}[ABCFGHJLPT][A-Z][0-9]{4}[A-Z][1-9A-Z]Z[0-9A-Z]$", "");
re.test(input);Limites
- Valide seulement la FORME : ne calcule pas la clé modulo 36. « 27AAAPL1234C1Z0 » a la bonne forme mais une clé fausse et passe ce motif. Le 5e caractère du PAN (initiale du nom) et l'existence du contribuable ne peuvent pas être vérifiés par une regex.
- Les règles « Z » en 14e position, « 13e caractère de 1 à 9 ou A à Z » et la clé viennent de python-stdnum et d'autres sources secondaires, pas des CGST Rules, qui ne fixent que la composition (code d'État, PAN, code d'entité, clé). Les codes d'État 25 et 28 sont acceptés, bien que la liste de la Zoho ne les cite pas : la liste officielle n'a pas pu être consultée.
- Le type de titulaire du PAN (4e caractère) est limité à A B C F G H J L P T, d'après la page TRACES ; « K », que certaines bibliothèques acceptent, est rejeté. Le code d'État 99 (juridiction centrale) et 96 ne sont pas acceptés.
- L'algorithme de la clé du PAN lui-même n'est pas public : le PAN n'est vérifié que pour sa forme. Les numéros du corpus, hors les deux exemples de bibliothèques, sont synthétiques avec une clé recalculée ; n'utilisez pas de vrais GSTIN dans vos tests.