Source code for validators.btc_address

import re
from hashlib import sha256

from .utils import validator

segwit_pattern = re.compile(
    r'^(bc|tc)[0-3][02-9ac-hj-np-z]{14,74}$')


def validate_segwit_address(addr):
    return segwit_pattern.match(addr)


def decode_base58(addr):
    alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
    return sum([
        (58 ** e) * alphabet.index(i)
        for e, i in enumerate(addr[::-1])
    ])


def validate_old_btc_address(addr):
    "Validate P2PKH and P2SH type address"
    if not len(addr) in range(25, 35):
        return False
    decoded_bytes = decode_base58(addr).to_bytes(25, "big")
    header = decoded_bytes[:-4]
    checksum = decoded_bytes[-4:]
    return checksum == sha256(sha256(header).digest()).digest()[:4]


[docs]@validator def btc_address(value): """ Return whether or not given value is a valid bitcoin address. If the value is valid bitcoin address this function returns ``True``, otherwise :class:`~validators.utils.ValidationFailure`. Full validation is implemented for P2PKH and P2SH addresses. For segwit addresses a regexp is used to provide a reasonable estimate on whether the address is valid. Examples:: >>> btc_address('3Cwgr2g7vsi1bXDUkpEnVoRLA9w4FZfC69') True :param value: Bitcoin address string to validate """ if not value or not isinstance(value, str): return False if value[:2] in ("bc", "tb"): return validate_segwit_address(value) return validate_old_btc_address(value)