1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Distributed under the MIT/X11 software license, see the accompanying
3 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
7 // Why base-58 instead of standard base-64 encoding?
8 // - Don't want 0OIl characters that look the same in some fonts and
9 // could be used to create visually identical looking account numbers.
10 // - A string with non-alphanumeric characters is not as easily accepted as an account number.
11 // - E-mail usually won't line-break if there's no punctuation to break at.
12 // - Doubleclicking selects the whole number as one word if it's all alphanumeric.
16 static const char* pszBase58
= "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
19 inline string
EncodeBase58(const unsigned char* pbegin
, const unsigned char* pend
)
25 // Convert big endian data to little endian
26 // Extra zero at the end make sure bignum will interpret as a positive number
27 vector
<unsigned char> vchTmp(pend
-pbegin
+1, 0);
28 reverse_copy(pbegin
, pend
, vchTmp
.begin());
30 // Convert little endian data to bignum
34 // Convert bignum to string
36 str
.reserve((pend
- pbegin
) * 138 / 100 + 1);
41 if (!BN_div(&dv
, &rem
, &bn
, &bn58
, pctx
))
42 throw bignum_error("EncodeBase58 : BN_div failed");
44 unsigned int c
= rem
.getulong();
48 // Leading zeroes encoded as base58 zeros
49 for (const unsigned char* p
= pbegin
; p
< pend
&& *p
== 0; p
++)
52 // Convert little endian string to big endian
53 reverse(str
.begin(), str
.end());
57 inline string
EncodeBase58(const vector
<unsigned char>& vch
)
59 return EncodeBase58(&vch
[0], &vch
[0] + vch
.size());
62 inline bool DecodeBase58(const char* psz
, vector
<unsigned char>& vchRet
)
72 // Convert big endian string to bignum
73 for (const char* p
= psz
; *p
; p
++)
75 const char* p1
= strchr(pszBase58
, *p
);
84 bnChar
.setulong(p1
- pszBase58
);
85 if (!BN_mul(&bn
, &bn
, &bn58
, pctx
))
86 throw bignum_error("DecodeBase58 : BN_mul failed");
90 // Get bignum as little endian data
91 vector
<unsigned char> vchTmp
= bn
.getvch();
93 // Trim off sign byte if present
94 if (vchTmp
.size() >= 2 && vchTmp
.end()[-1] == 0 && vchTmp
.end()[-2] >= 0x80)
95 vchTmp
.erase(vchTmp
.end()-1);
97 // Restore leading zeros
98 int nLeadingZeros
= 0;
99 for (const char* p
= psz
; *p
== pszBase58
[0]; p
++)
101 vchRet
.assign(nLeadingZeros
+ vchTmp
.size(), 0);
103 // Convert little endian data to big endian
104 reverse_copy(vchTmp
.begin(), vchTmp
.end(), vchRet
.end() - vchTmp
.size());
108 inline bool DecodeBase58(const string
& str
, vector
<unsigned char>& vchRet
)
110 return DecodeBase58(str
.c_str(), vchRet
);
117 inline string
EncodeBase58Check(const vector
<unsigned char>& vchIn
)
119 // add 4-byte hash check to the end
120 vector
<unsigned char> vch(vchIn
);
121 uint256 hash
= Hash(vch
.begin(), vch
.end());
122 vch
.insert(vch
.end(), (unsigned char*)&hash
, (unsigned char*)&hash
+ 4);
123 return EncodeBase58(vch
);
126 inline bool DecodeBase58Check(const char* psz
, vector
<unsigned char>& vchRet
)
128 if (!DecodeBase58(psz
, vchRet
))
130 if (vchRet
.size() < 4)
135 uint256 hash
= Hash(vchRet
.begin(), vchRet
.end()-4);
136 if (memcmp(&hash
, &vchRet
.end()[-4], 4) != 0)
141 vchRet
.resize(vchRet
.size()-4);
145 inline bool DecodeBase58Check(const string
& str
, vector
<unsigned char>& vchRet
)
147 return DecodeBase58Check(str
.c_str(), vchRet
);
155 #define ADDRESSVERSION ((unsigned char)(fTestNet ? 111 : 0))
157 inline string
Hash160ToAddress(uint160 hash160
)
159 // add 1-byte version number to the front
160 vector
<unsigned char> vch(1, ADDRESSVERSION
);
161 vch
.insert(vch
.end(), UBEGIN(hash160
), UEND(hash160
));
162 return EncodeBase58Check(vch
);
165 inline bool AddressToHash160(const char* psz
, uint160
& hash160Ret
)
167 vector
<unsigned char> vch
;
168 if (!DecodeBase58Check(psz
, vch
))
172 unsigned char nVersion
= vch
[0];
173 if (vch
.size() != sizeof(hash160Ret
) + 1)
175 memcpy(&hash160Ret
, &vch
[1], sizeof(hash160Ret
));
176 return (nVersion
<= ADDRESSVERSION
);
179 inline bool AddressToHash160(const string
& str
, uint160
& hash160Ret
)
181 return AddressToHash160(str
.c_str(), hash160Ret
);
184 inline bool IsValidBitcoinAddress(const char* psz
)
187 return AddressToHash160(psz
, hash160
);
190 inline bool IsValidBitcoinAddress(const string
& str
)
192 return IsValidBitcoinAddress(str
.c_str());
198 inline string
PubKeyToAddress(const vector
<unsigned char>& vchPubKey
)
200 return Hash160ToAddress(Hash160(vchPubKey
));