Regex adresse Bitcoin
Une adresse Bitcoin, ce n'est pas qu'un seul format : les adresses historiques P2PKH/P2SH (« 1… », « 3… ») utilisent l'alphabet Base58, mais le format natif SegWit Bech32 (« bc1… », BIP 173) utilise un alphabet de 32 caractères complètement différent, qui exclut délibérément le « 1 », le « b », le « i » et le « o » pour éviter toute confusion visuelle. Une bibliothèque npm réelle applique pourtant l'alphabet Base58 à une adresse Bech32 — les deux alphabets n'ayant presque rien en commun, une bonne partie des adresses Bech32 légitimes échoue. Deux autres tentatives ignorent purement et simplement Bech32. Voici un motif qui gère les deux systèmes correctement, comparé à ces trois tentatives.
/^(?:[13][a-km-zA-HJ-NP-Z1-9]{25,34}|bc1[qpzry9x8gf2tvdw0s3jn54khce6mua7l]{6,87})$/passe 20/20 cas
Comparatif des patterns existants
| Source | pattern | Score sur le corpus | ReDoS |
|---|---|---|---|
| kevva/bitcoin-regex (package npm réel) — ignore complètement Bech32, toute adresse SegWit native moderne (« bc1… »), pourtant majoritaire aujourd'hui, est rejetée | (?:^(?:[13][a-km-zA-HJ-NP-Z1-9]{25,34})$) | 18 / 20 | sûr |
| Article technique mokagio (2014) — même limitation, aucune branche pour Bech32 ; l'auteur reconnaît lui-même que la spec Bitcoin déconseille cette approche sans vérification de checksum | ^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$ | 18 / 20 | sûr |
| iHateRegex — applique l'alphabet Base58 (qui exclut 0/O/I/l) à la branche bc1, alors que Bech32 utilise un alphabet totalement différent (exclut 1/b/i/o) ; plage de longueur trop courte pour du P2WSH | ^(bc1|[13])[a-zA-HJ-NP-Z0-9]{25,39}$ | 17 / 20 | sûr |
Implémentation
const re = new RegExp("^(?:[13][a-km-zA-HJ-NP-Z1-9]{25,34}|bc1[qpzry9x8gf2tvdw0s3jn54khce6mua7l]{6,87})$", "");
re.test(input);Limites
- Valide seulement la FORME et l'alphabet : ne calcule ni le checksum Base58Check (SHA-256 double, 4 premiers octets) des adresses legacy, ni le checksum polynomial Bech32 — une adresse syntaxiquement valide selon ce motif peut avoir un checksum faux et ne correspondre à aucune adresse réellement dérivable d'une clé publique.
- Ne distingue pas les adresses P2PKH (préfixe « 1 ») des adresses P2SH (préfixe « 3 ») dans son résultat, alors qu'elles correspondent à des mécanismes de verrouillage différents (clé publique simple vs script arbitraire, souvent multi-signature).
- N'accepte que le réseau principal (mainnet) : le réseau de test (testnet) utilise ses propres préfixes (« m »/« n » pour P2PKH, « 2 » pour P2SH, « tb1 » pour Bech32), non couverts ici.
- La casse Bech32 doit être uniformément minuscule ou uniformément majuscule, jamais mélangée (le checksum polynomial en dépend) : ce motif n'accepte que la forme tout-minuscule, la plus répandue en pratique dans les portefeuilles et explorateurs de blocs.