Fix incorrect Markdown link
[bitcoinplatinum.git] / contrib / testgen / base58.py
blob816d40b49c59cf3986a864eb63d82a8d88272c80
1 # Copyright (c) 2012-2017 The Bitcoin Core developers
2 # Distributed under the MIT software license, see the accompanying
3 # file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 '''
5 Bitcoin base58 encoding and decoding.
7 Based on https://bitcointalk.org/index.php?topic=1026.0 (public domain)
8 '''
9 import hashlib
11 # for compatibility with following code...
12 class SHA256:
13 new = hashlib.sha256
15 if str != bytes:
16 # Python 3.x
17 def ord(c):
18 return c
19 def chr(n):
20 return bytes( (n,) )
22 __b58chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
23 __b58base = len(__b58chars)
24 b58chars = __b58chars
26 def b58encode(v):
27 """ encode v, which is a string of bytes, to base58.
28 """
29 long_value = 0
30 for (i, c) in enumerate(v[::-1]):
31 long_value += (256**i) * ord(c)
33 result = ''
34 while long_value >= __b58base:
35 div, mod = divmod(long_value, __b58base)
36 result = __b58chars[mod] + result
37 long_value = div
38 result = __b58chars[long_value] + result
40 # Bitcoin does a little leading-zero-compression:
41 # leading 0-bytes in the input become leading-1s
42 nPad = 0
43 for c in v:
44 if c == '\0': nPad += 1
45 else: break
47 return (__b58chars[0]*nPad) + result
49 def b58decode(v, length = None):
50 """ decode v into a string of len bytes
51 """
52 long_value = 0
53 for (i, c) in enumerate(v[::-1]):
54 long_value += __b58chars.find(c) * (__b58base**i)
56 result = bytes()
57 while long_value >= 256:
58 div, mod = divmod(long_value, 256)
59 result = chr(mod) + result
60 long_value = div
61 result = chr(long_value) + result
63 nPad = 0
64 for c in v:
65 if c == __b58chars[0]: nPad += 1
66 else: break
68 result = chr(0)*nPad + result
69 if length is not None and len(result) != length:
70 return None
72 return result
74 def checksum(v):
75 """Return 32-bit checksum based on SHA256"""
76 return SHA256.new(SHA256.new(v).digest()).digest()[0:4]
78 def b58encode_chk(v):
79 """b58encode a string, with 32-bit checksum"""
80 return b58encode(v + checksum(v))
82 def b58decode_chk(v):
83 """decode a base58 string, check and remove checksum"""
84 result = b58decode(v)
85 if result is None:
86 return None
87 if result[-4:] == checksum(result[:-4]):
88 return result[:-4]
89 else:
90 return None
92 def get_bcaddress_version(strAddress):
93 """ Returns None if strAddress is invalid. Otherwise returns integer version of address. """
94 addr = b58decode_chk(strAddress)
95 if addr is None or len(addr)!=21: return None
96 version = addr[0]
97 return ord(version)
99 if __name__ == '__main__':
100 # Test case (from http://gitorious.org/bitcoin/python-base58.git)
101 assert get_bcaddress_version('15VjRaDX9zpbA8LVnbrCAFzrVzN7ixHNsC') is 0
102 _ohai = 'o hai'.encode('ascii')
103 _tmp = b58encode(_ohai)
104 assert _tmp == 'DYB3oMS'
105 assert b58decode(_tmp, 5) == _ohai
106 print("Tests passed")