-
Notifications
You must be signed in to change notification settings - Fork 15
/
base58.py
130 lines (105 loc) · 3.42 KB
/
base58.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#!/usr/bin/env python
"""encode/decode base58 in the same way that Bitcoin does"""
import hashlib
import math
__b58chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
__b58base = len(__b58chars)
getNewRIPEMD160 = None
getNewSHA256 = None
def b58encode(v):
""" encode v, which is a string of bytes, to base58.
"""
long_value = 0L
for (i, c) in enumerate(v[::-1]):
long_value += (256**i) * ord(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) + result
def b58decode(v, length):
""" decode v into a string of len bytes
"""
long_value = 0L
for (i, c) in enumerate(v[::-1]):
long_value += __b58chars.find(c) * (__b58base**i)
result = ''
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
else: break
result = chr(0)*nPad + result
if length is not None and len(result) != length:
return None
return result
def getNewRIPEMD160ByCrypto(public_key=""):
return RIPEMD160.new(public_key)
def getNewRIPEMD160ByHashlib(public_key=""):
newRIPEMD160 = hashlib.new('ripemd160')
newRIPEMD160.update(public_key)
return newRIPEMD160
def getNewSHA256ByCrypto(public_key=""):
return SHA256.new(public_key)
def getNewSHA256ByHashlib(public_key=""):
return hashlib.sha256(public_key)
try:
# Python Crypto library is at: http://www.dlitz.net/software/pycrypto/
# Needed for RIPEMD160 hash function, used to compute
# Bitcoin addresses from internal public keys.
import Crypto.Hash.RIPEMD160 as RIPEMD160
getNewRIPEMD160 = getNewRIPEMD160ByCrypto
except ImportError:
try:
test = getNewRIPEMD160ByHashlib()
getNewRIPEMD160 = getNewRIPEMD160ByHashlib
except ImportError:
print("Can not import RIPEMD160")
try:
# Python Crypto library is at: http://www.dlitz.net/software/pycrypto/
# Needed for RIPEMD160 hash function, used to compute
# Bitcoin addresses from internal public keys.
import Crypto.Hash.SHA256 as SHA256
getNewSHA256 = getNewSHA256ByCrypto
except ImportError:
try:
test = getNewSHA256ByHashlib()
getNewSHA256 = getNewSHA256ByHashlib
except ImportError:
print("Can not import SHA256")
def hash_160(public_key):
if getNewSHA256 == None or getNewRIPEMD160 == None:
return ''
h1 = getNewSHA256(public_key).digest()
h2 = getNewRIPEMD160(h1).digest()
return h2
def public_key_to_bc_address(public_key):
h160 = hash_160(public_key)
return hash_160_to_bc_address(h160)
def hash_160_to_bc_address(h160):
if getNewSHA256 == None:
return ''
vh160 = "\x00"+h160 # \x00 is version 0
h3=getNewSHA256(getNewSHA256(vh160).digest()).digest()
addr=vh160+h3[0:4]
return b58encode(addr)
def bc_address_to_hash_160(addr):
bytes = b58decode(addr, 25)
return bytes[1:21]
if __name__ == '__main__':
x = '005cc87f4a3fdfe3a2346b6953267ca867282630d3f9b78e64'.decode('hex_codec')
encoded = b58encode(x)
print encoded, '19TbMSWwHvnxAKy12iNm3KdbGfzfaMFViT'
print b58decode(encoded, len(x)).encode('hex_codec'), x.encode('hex_codec')