Encode a byte sequence as a base58-encoded string
| 503 | |
| 504 | // Encode a byte sequence as a base58-encoded string |
| 505 | inline std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend, const fc::yield_function_t& yield) |
| 506 | { |
| 507 | CAutoBN_CTX pctx; |
| 508 | CBigNum bn58 = 58; |
| 509 | CBigNum bn0 = 0; |
| 510 | |
| 511 | // Convert big endian data to little endian |
| 512 | // Extra zero at the end make sure bignum will interpret as a positive number |
| 513 | std::vector<unsigned char> vchTmp(pend-pbegin+1, 0); |
| 514 | yield(); |
| 515 | reverse_copy(pbegin, pend, vchTmp.begin()); |
| 516 | yield(); |
| 517 | |
| 518 | // Convert little endian data to bignum |
| 519 | CBigNum bn; |
| 520 | bn.setvch(vchTmp); |
| 521 | |
| 522 | // Convert bignum to std::string |
| 523 | std::string str; |
| 524 | // Expected size increase from base58 conversion is approximately 137% |
| 525 | // use 138% to be safe |
| 526 | str.reserve((pend - pbegin) * 138 / 100 + 1); |
| 527 | CBigNum dv; |
| 528 | CBigNum rem; |
| 529 | while (bn > bn0) |
| 530 | { |
| 531 | yield(); |
| 532 | if (!BN_div(dv.to_bignum(), rem.to_bignum(), bn.to_bignum(), bn58.to_bignum(), pctx)) |
| 533 | throw bignum_error("EncodeBase58 : BN_div failed"); |
| 534 | bn = dv; |
| 535 | unsigned int c = rem.getulong(); |
| 536 | str += pszBase58[c]; |
| 537 | } |
| 538 | |
| 539 | // Leading zeroes encoded as base58 zeros |
| 540 | for (const unsigned char* p = pbegin; p < pend && *p == 0; p++) |
| 541 | str += pszBase58[0]; |
| 542 | |
| 543 | yield(); |
| 544 | // Convert little endian std::string to big endian |
| 545 | reverse(str.begin(), str.end()); |
| 546 | // slog( "Encode '%s'", str.c_str() ); |
| 547 | yield(); |
| 548 | |
| 549 | return str; |
| 550 | } |
| 551 | |
| 552 | // Encode a byte vector as a base58-encoded string |
| 553 | inline std::string EncodeBase58(const std::vector<unsigned char>& vch, const fc::yield_function_t& yield) |