std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend) { // Skip & count leading zeroes. int zeroes = 0; while (pbegin != pend && *pbegin == 0) { pbegin++; zeroes++; } // Allocate enough space in big-endian base58 representation. std::vector<unsigned char> b58((pend - pbegin) * 138 / 100 + 1); // log(256) / log(58), rounded up. // Process the bytes. while (pbegin != pend) { int carry = *pbegin; // Apply "b58 = b58 * 256 + ch". for (std::vector<unsigned char>::reverse_iterator it = b58.rbegin(); it != b58.rend(); it++) { carry += 256 * (*it); *it = carry % 58; carry /= 58; } assert(carry == 0); pbegin++; } // Skip leading zeroes in base58 result. std::vector<unsigned char>::iterator it = b58.begin(); while (it != b58.end() && *it == 0) it++; // Translate the result into a string. std::string str; str.reserve(zeroes + (b58.end() - it)); str.assign(zeroes, '1'); while (it != b58.end()) str += pszBase58[*(it++)]; return str; }
std::string crypt_ec_helper::to_base58(const EC_POINT* public_key) { unsigned char *ret = new unsigned char[2048]; EC_GROUP *ecgrp = EC_GROUP_new_by_curve_name(NID_secp256k1); size_t len = EC_POINT_point2oct(ecgrp, public_key, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL); EC_POINT_point2oct(ecgrp, public_key, POINT_CONVERSION_UNCOMPRESSED, ret, len, NULL); unsigned char* pbegin = ret; unsigned char* pend = ret + len; // Skip & count leading zeroes. int zeroes = 0; int length = 0; while (pbegin != pend && *pbegin == 0) { pbegin++; zeroes++; } // Allocate enough space in big-endian base58 representation. int size = (pend - pbegin) * 138 / 100 + 1; // log(256) / log(58), rounded up. std::vector<unsigned char> b58(size); // Process the bytes. while (pbegin != pend) { int carry = *pbegin; int i = 0; // Apply "b58 = b58 * 256 + ch". for (std::vector<unsigned char>::reverse_iterator it = b58.rbegin(); (carry != 0 || i < length) && (it != b58.rend()); it++, i++) { carry += 256 * (*it); *it = carry % 58; carry /= 58; } assert(carry == 0); length = i; pbegin++; } // Skip leading zeroes in base58 result. std::vector<unsigned char>::iterator it = b58.begin() + (size - length); while (it != b58.end() && *it == 0) it++; // Translate the result into a string. std::string str; str.reserve(zeroes + (b58.end() - it)); str.assign(zeroes, '1'); while (it != b58.end()) str += pszBase58[*(it++)]; free(ret); EC_GROUP_free(ecgrp); return str; }
std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend) { // Skip & count leading zeroes. size_t zeroes = 0; size_t length = 0; while (pbegin != pend && *pbegin == 0) { pbegin++; zeroes++; } // Allocate enough space in big-endian base58 representation. size_t size = static_cast<size_t>((pend - pbegin) * 138 / 100 + 1); // log(256) / log(58), rounded up. std::vector<unsigned char> b58(size); // Process the bytes. while (pbegin != pend) { int carry = *pbegin; size_t i = 0; // Apply "b58 = b58 * 256 + ch". for (auto it = b58.rbegin(); (carry != 0 || i < length) && (it != b58.rend()); ++it, ++i) { carry += 256 * (*it); *it = carry % 58; carry /= 58; } assert(carry == 0); length = i; pbegin++; } // Skip leading zeroes in base58 result. auto it = b58.begin(); std::advance(it, static_cast<int64_t>(size - length)); while (it != b58.end() && *it == 0) ++it; // Translate the result into a string. std::string str; str.reserve(zeroes + static_cast<size_t>(std::distance(it, b58.end()))); str.assign(zeroes, '1'); while (it != b58.end()) str += pszBase58[*(it++)]; return str; }