git / moonbite-core / contrib/testgen/base58.py · raw

# Copyright (c) 2012-2018 The Bitcoin Core developers# Distributed under the MIT software license, see the accompanying# file COPYING or http://www.opensource.org/licenses/mit-license.php.'''Bitcoin base58 encoding and decoding.Based on https://bitcointalk.org/index.php?topic=1026.0 (public domain)'''import hashlib# for compatibility with following code...class SHA256:    new = hashlib.sha256if str != bytes:    # Python 3.x    def ord(c):        return c    def chr(n):        return bytes( (n,) )__b58chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'__b58base = len(__b58chars)b58chars = __b58charsdef b58encode(v):    """ encode v, which is a string of bytes, to base58.    """    long_value = 0    for (i, c) in enumerate(v[::-1]):        if isinstance(c, str):            c = ord(c)        long_value += (256**i) * c    result = ''    while long_value >= __b58base:        div, mod = divmod(long_value, __b58base)        result = __b58chars[mod] + result        long_value = div    result = __b58chars[long_value] + result    # Bitcoin does a little leading-zero-compression:    # leading 0-bytes in the input become leading-1s    nPad = 0    for c in v:        if c == 0:            nPad += 1        else:            break    return (__b58chars[0]*nPad) + resultdef b58decode(v, length = None):    """ decode v into a string of len bytes    """    long_value = 0    for i, c in enumerate(v[::-1]):        pos = __b58chars.find(c)        assert pos != -1        long_value += pos * (__b58base**i)    result = bytes()    while long_value >= 256:        div, mod = divmod(long_value, 256)        result = chr(mod) + result        long_value = div    result = chr(long_value) + result    nPad = 0    for c in v:        if c == __b58chars[0]:            nPad += 1            continue        break    result = bytes(nPad) + result    if length is not None and len(result) != length:        return None    return resultdef checksum(v):    """Return 32-bit checksum based on SHA256"""    return SHA256.new(SHA256.new(v).digest()).digest()[0:4]def b58encode_chk(v):    """b58encode a string, with 32-bit checksum"""    return b58encode(v + checksum(v))def b58decode_chk(v):    """decode a base58 string, check and remove checksum"""    result = b58decode(v)    if result is None:        return None    if result[-4:] == checksum(result[:-4]):        return result[:-4]    else:        return Nonedef get_bcaddress_version(strAddress):    """ Returns None if strAddress is invalid.  Otherwise returns integer version of address. """    addr = b58decode_chk(strAddress)    if addr is None or len(addr)!=21:        return None    version = addr[0]    return ord(version)if __name__ == '__main__':    # Test case (from http://gitorious.org/bitcoin/python-base58.git)    assert get_bcaddress_version('15VjRaDX9zpbA8LVnbrCAFzrVzN7ixHNsC') == 0    _ohai = 'o hai'.encode('ascii')    _tmp = b58encode(_ohai)    assert _tmp == 'DYB3oMS'    assert b58decode(_tmp, 5) == _ohai    print("Tests passed")