-
+ D641E49142B70D90E2BE8F212FF3A2583EE44701598D8870CEF1B7BE011E5D6EF7A0295242CE65624E1C57A0DD0A3EC7A465D84649BFDB3F52CEDC4919AB9665
bitcoin/src/base58.h
(0 . 0)(1 . 354)
115 // /****************************\
116 // * EXPERIMENTAL BRANCH. *
117 // * FOR LABORATORY USE ONLY. *
118 // ********************************
119 // ************
120 // **************
121 // ****************
122 // **** **** ****
123 // *** *** ***
124 // *** *** ***
125 // *** * * **
126 // ******** ********
127 // ******* ******
128 // *** **
129 // * ******* **
130 // ** * * * * *
131 // ** * * ***
132 // **** * * * * ****
133 // **** *** * * ** ***
134 // **** ********* ******
135 // ******* ***** *******
136 // ********* ****** **
137 // ** ****** ******
138 // ** ******* **
139 // ** ******* ***
140 // **** ******** ************
141 // ************ ************
142 // ******** *******
143 // ****** ****
144 // *** ***
145 // ********************************
146 // Copyright (c) 2009-2010 Satoshi Nakamoto
147 // Copyright (c) 2011 The Bitcoin Developers
148 // Distributed under the MIT/X11 software license, see the accompanying
149 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
150
151
152 //
153 // Why base-58 instead of standard base-64 encoding?
154 // - Don't want 0OIl characters that look the same in some fonts and
155 // could be used to create visually identical looking account numbers.
156 // - A string with non-alphanumeric characters is not as easily accepted as an account number.
157 // - E-mail usually won't line-break if there's no punctuation to break at.
158 // - Doubleclicking selects the whole number as one word if it's all alphanumeric.
159 //
160 #ifndef BITCOIN_BASE58_H
161 #define BITCOIN_BASE58_H
162
163 #include <string>
164 #include <vector>
165 #include "bignum.h"
166
167 static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
168
169 // Encode a byte sequence as a base58-encoded string
170 inline std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend)
171 {
172 CAutoBN_CTX pctx;
173 CBigNum bn58 = 58;
174 CBigNum bn0 = 0;
175
176 // Convert big endian data to little endian
177 // Extra zero at the end make sure bignum will interpret as a positive number
178 std::vector<unsigned char> vchTmp(pend-pbegin+1, 0);
179 reverse_copy(pbegin, pend, vchTmp.begin());
180
181 // Convert little endian data to bignum
182 CBigNum bn;
183 bn.setvch(vchTmp);
184
185 // Convert bignum to std::string
186 std::string str;
187 // Expected size increase from base58 conversion is approximately 137%
188 // use 138% to be safe
189 str.reserve((pend - pbegin) * 138 / 100 + 1);
190 CBigNum dv;
191 CBigNum rem;
192 while (bn > bn0)
193 {
194 if (!BN_div(&dv, &rem, &bn, &bn58, pctx))
195 throw bignum_error("EncodeBase58 : BN_div failed");
196 bn = dv;
197 unsigned int c = rem.getulong();
198 str += pszBase58[c];
199 }
200
201 // Leading zeroes encoded as base58 zeros
202 for (const unsigned char* p = pbegin; p < pend && *p == 0; p++)
203 str += pszBase58[0];
204
205 // Convert little endian std::string to big endian
206 reverse(str.begin(), str.end());
207 return str;
208 }
209
210 // Encode a byte vector as a base58-encoded string
211 inline std::string EncodeBase58(const std::vector<unsigned char>& vch)
212 {
213 return EncodeBase58(&vch[0], &vch[0] + vch.size());
214 }
215
216 // Decode a base58-encoded string psz into byte vector vchRet
217 // returns true if decoding is succesful
218 inline bool DecodeBase58(const char* psz, std::vector<unsigned char>& vchRet)
219 {
220 CAutoBN_CTX pctx;
221 vchRet.clear();
222 CBigNum bn58 = 58;
223 CBigNum bn = 0;
224 CBigNum bnChar;
225 while (isspace(*psz))
226 psz++;
227
228 // Convert big endian string to bignum
229 for (const char* p = psz; *p; p++)
230 {
231 const char* p1 = strchr(pszBase58, *p);
232 if (p1 == NULL)
233 {
234 while (isspace(*p))
235 p++;
236 if (*p != '\0')
237 return false;
238 break;
239 }
240 bnChar.setulong(p1 - pszBase58);
241 if (!BN_mul(&bn, &bn, &bn58, pctx))
242 throw bignum_error("DecodeBase58 : BN_mul failed");
243 bn += bnChar;
244 }
245
246 // Get bignum as little endian data
247 std::vector<unsigned char> vchTmp = bn.getvch();
248
249 // Trim off sign byte if present
250 if (vchTmp.size() >= 2 && vchTmp.end()[-1] == 0 && vchTmp.end()[-2] >= 0x80)
251 vchTmp.erase(vchTmp.end()-1);
252
253 // Restore leading zeros
254 int nLeadingZeros = 0;
255 for (const char* p = psz; *p == pszBase58[0]; p++)
256 nLeadingZeros++;
257 vchRet.assign(nLeadingZeros + vchTmp.size(), 0);
258
259 // Convert little endian data to big endian
260 reverse_copy(vchTmp.begin(), vchTmp.end(), vchRet.end() - vchTmp.size());
261 return true;
262 }
263
264 // Decode a base58-encoded string str into byte vector vchRet
265 // returns true if decoding is succesful
266 inline bool DecodeBase58(const std::string& str, std::vector<unsigned char>& vchRet)
267 {
268 return DecodeBase58(str.c_str(), vchRet);
269 }
270
271
272
273
274 // Encode a byte vector to a base58-encoded string, including checksum
275 inline std::string EncodeBase58Check(const std::vector<unsigned char>& vchIn)
276 {
277 // add 4-byte hash check to the end
278 std::vector<unsigned char> vch(vchIn);
279 uint256 hash = Hash(vch.begin(), vch.end());
280 vch.insert(vch.end(), (unsigned char*)&hash, (unsigned char*)&hash + 4);
281 return EncodeBase58(vch);
282 }
283
284 // Decode a base58-encoded string psz that includes a checksum, into byte vector vchRet
285 // returns true if decoding is succesful
286 inline bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRet)
287 {
288 if (!DecodeBase58(psz, vchRet))
289 return false;
290 if (vchRet.size() < 4)
291 {
292 vchRet.clear();
293 return false;
294 }
295 uint256 hash = Hash(vchRet.begin(), vchRet.end()-4);
296 if (memcmp(&hash, &vchRet.end()[-4], 4) != 0)
297 {
298 vchRet.clear();
299 return false;
300 }
301 vchRet.resize(vchRet.size()-4);
302 return true;
303 }
304
305 // Decode a base58-encoded string str that includes a checksum, into byte vector vchRet
306 // returns true if decoding is succesful
307 inline bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRet)
308 {
309 return DecodeBase58Check(str.c_str(), vchRet);
310 }
311
312
313
314
315
316 // Base class for all base58-encoded data
317 class CBase58Data
318 {
319 protected:
320 // the version byte
321 unsigned char nVersion;
322
323 // the actually encoded data
324 std::vector<unsigned char> vchData;
325
326 CBase58Data()
327 {
328 nVersion = 0;
329 vchData.clear();
330 }
331
332 ~CBase58Data()
333 {
334 // zero the memory, as it may contain sensitive data
335 if (!vchData.empty())
336 memset(&vchData[0], 0, vchData.size());
337 }
338
339 void SetData(int nVersionIn, const void* pdata, size_t nSize)
340 {
341 nVersion = nVersionIn;
342 vchData.resize(nSize);
343 if (!vchData.empty())
344 memcpy(&vchData[0], pdata, nSize);
345 }
346
347 void SetData(int nVersionIn, const unsigned char *pbegin, const unsigned char *pend)
348 {
349 SetData(nVersionIn, (void*)pbegin, pend - pbegin);
350 }
351
352 public:
353 bool SetString(const char* psz)
354 {
355 std::vector<unsigned char> vchTemp;
356 DecodeBase58Check(psz, vchTemp);
357 if (vchTemp.empty())
358 {
359 vchData.clear();
360 nVersion = 0;
361 return false;
362 }
363 nVersion = vchTemp[0];
364 vchData.resize(vchTemp.size() - 1);
365 if (!vchData.empty())
366 memcpy(&vchData[0], &vchTemp[1], vchData.size());
367 memset(&vchTemp[0], 0, vchTemp.size());
368 return true;
369 }
370
371 bool SetString(const std::string& str)
372 {
373 return SetString(str.c_str());
374 }
375
376 std::string ToString() const
377 {
378 std::vector<unsigned char> vch(1, nVersion);
379 vch.insert(vch.end(), vchData.begin(), vchData.end());
380 return EncodeBase58Check(vch);
381 }
382
383 int CompareTo(const CBase58Data& b58) const
384 {
385 if (nVersion < b58.nVersion) return -1;
386 if (nVersion > b58.nVersion) return 1;
387 if (vchData < b58.vchData) return -1;
388 if (vchData > b58.vchData) return 1;
389 return 0;
390 }
391
392 bool operator==(const CBase58Data& b58) const { return CompareTo(b58) == 0; }
393 bool operator<=(const CBase58Data& b58) const { return CompareTo(b58) <= 0; }
394 bool operator>=(const CBase58Data& b58) const { return CompareTo(b58) >= 0; }
395 bool operator< (const CBase58Data& b58) const { return CompareTo(b58) < 0; }
396 bool operator> (const CBase58Data& b58) const { return CompareTo(b58) > 0; }
397 };
398
399 // base58-encoded bitcoin addresses
400 // Addresses have version 0 or 111 (testnet)
401 // The data vector contains RIPEMD160(SHA256(pubkey)), where pubkey is the serialized public key
402 class CBitcoinAddress : public CBase58Data
403 {
404 public:
405 bool SetHash160(const uint160& hash160)
406 {
407 SetData(fTestNet ? 111 : 0, &hash160, 20);
408 return true;
409 }
410
411 bool SetPubKey(const std::vector<unsigned char>& vchPubKey)
412 {
413 return SetHash160(Hash160(vchPubKey));
414 }
415
416 bool IsValid() const
417 {
418 int nExpectedSize = 20;
419 bool fExpectTestNet = false;
420 switch(nVersion)
421 {
422 case 0:
423 break;
424
425 case 111:
426 fExpectTestNet = true;
427 break;
428
429 default:
430 return false;
431 }
432 return fExpectTestNet == fTestNet && vchData.size() == nExpectedSize;
433 }
434
435 CBitcoinAddress()
436 {
437 }
438
439 CBitcoinAddress(uint160 hash160In)
440 {
441 SetHash160(hash160In);
442 }
443
444 CBitcoinAddress(const std::vector<unsigned char>& vchPubKey)
445 {
446 SetPubKey(vchPubKey);
447 }
448
449 CBitcoinAddress(const std::string& strAddress)
450 {
451 SetString(strAddress);
452 }
453
454 CBitcoinAddress(const char* pszAddress)
455 {
456 SetString(pszAddress);
457 }
458
459 uint160 GetHash160() const
460 {
461 assert(vchData.size() == 20);
462 uint160 hash160;
463 memcpy(&hash160, &vchData[0], 20);
464 return hash160;
465 }
466 };
467
468 #endif