The following regex should work for validating that a string starts with one of xpub
, ypub
, Ypub
, zpub
, Zpub
, tpub
, upub
, Upub
, vpub
or Vpub
and is followed by 79-108 characters that are one of 123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz
(the Base58 alphabet) which is as close as you can get to validating BIP32 keys with regex:
^([xyYzZtuUvV]pub[1-9A-HJ-NP-Za-km-z]{79,108})$
(try at: https://regexr.com/6cn9a)
If you want to accept BIP32 keys that optionally include the ?c={timestamp}&h={bip}
arguments, then add (?:(?:$|\?)((?!.*&c=)c=\d{10}|(?!.*&h=)h=bip\d{2,3})(?:(?=(?:&c=|&h=))&(c=\d{10}|h=bip\d{2,3}))?)?
at the end, like this:
^([xyYzZtuUvV]pub[1-9A-HJ-NP-Za-km-z]{79,108})(?:(?:$|\?)((?!.*&c=)c=\d{10}|(?!.*&h=)h=bip\d{2,3})(?:(?=(?:&c=|&h=))&(c=\d{10}|h=bip\d{2,3}))?)?$
(try at: https://regexr.com/6cn9s - this will check that c
is a valid 10-digit UNIX timestamp, h
is bip{2-3 digit number}
, that there is at most one of each parameter, and allow parameters to be in either order.)
However, a more accurate way to test that a BIP32 key is valid is to simply decode it with Base58Check (similar to how regular Bitcoin addresses are encoded), verify that the checksum is valid, and check that the length of the decoded data is exactly 78 bytes.