Berkeley DB v6 compatibility fix
[bitcoinplatinum.git] / contrib / testgen / base58.py
blobb716495145f7772cdea37fdd0a7cd1c8caf9dc12
1 '''
2 Bitcoin base58 encoding and decoding.
4 Based on https://bitcointalk.org/index.php?topic=1026.0 (public domain)
5 '''
6 import hashlib
8 # for compatibility with following code...
9 class SHA256:
10 new = hashlib.sha256
12 if str != bytes:
13 # Python 3.x
14 def ord(c):
15 return c
16 def chr(n):
17 return bytes( (n,) )
19 __b58chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
20 __b58base = len(__b58chars)
21 b58chars = __b58chars
23 def b58encode(v):
24 """ encode v, which is a string of bytes, to base58.
25 """
26 long_value = 0
27 for (i, c) in enumerate(v[::-1]):
28 long_value += (256**i) * ord(c)
30 result = ''
31 while long_value >= __b58base:
32 div, mod = divmod(long_value, __b58base)
33 result = __b58chars[mod] + result
34 long_value = div
35 result = __b58chars[long_value] + result
37 # Bitcoin does a little leading-zero-compression:
38 # leading 0-bytes in the input become leading-1s
39 nPad = 0
40 for c in v:
41 if c == '\0': nPad += 1
42 else: break
44 return (__b58chars[0]*nPad) + result
46 def b58decode(v, length = None):
47 """ decode v into a string of len bytes
48 """
49 long_value = 0
50 for (i, c) in enumerate(v[::-1]):
51 long_value += __b58chars.find(c) * (__b58base**i)
53 result = bytes()
54 while long_value >= 256:
55 div, mod = divmod(long_value, 256)
56 result = chr(mod) + result
57 long_value = div
58 result = chr(long_value) + result
60 nPad = 0
61 for c in v:
62 if c == __b58chars[0]: nPad += 1
63 else: break
65 result = chr(0)*nPad + result
66 if length is not None and len(result) != length:
67 return None
69 return result
71 def checksum(v):
72 """Return 32-bit checksum based on SHA256"""
73 return SHA256.new(SHA256.new(v).digest()).digest()[0:4]
75 def b58encode_chk(v):
76 """b58encode a string, with 32-bit checksum"""
77 return b58encode(v + checksum(v))
79 def b58decode_chk(v):
80 """decode a base58 string, check and remove checksum"""
81 result = b58decode(v)
82 if result is None:
83 return None
84 h3 = checksum(result[:-4])
85 if result[-4:] == checksum(result[:-4]):
86 return result[:-4]
87 else:
88 return None
90 def get_bcaddress_version(strAddress):
91 """ Returns None if strAddress is invalid. Otherwise returns integer version of address. """
92 addr = b58decode_chk(strAddress)
93 if addr is None or len(addr)!=21: return None
94 version = addr[0]
95 return ord(version)
97 if __name__ == '__main__':
98 # Test case (from http://gitorious.org/bitcoin/python-base58.git)
99 assert get_bcaddress_version('15VjRaDX9zpbA8LVnbrCAFzrVzN7ixHNsC') is 0
100 _ohai = 'o hai'.encode('ascii')
101 _tmp = b58encode(_ohai)
102 assert _tmp == 'DYB3oMS'
103 assert b58decode(_tmp, 5) == _ohai
104 print("Tests passed")