Merge #8736: base58: Improve DecodeBase58 performance.

e892dc1 Use prefix operator in for loop of DecodeBase58. (Jiaxing Wang)
159ed95 base58: Improve DecodeBase58 performance. (Jiaxing Wang)
This commit is contained in:
Wladimir J. van der Laan 2016-11-07 11:50:45 +01:00
commit 5fa7b07565
No known key found for this signature in database
GPG key ID: 74810B012346C9A6

View file

@ -25,12 +25,14 @@ bool DecodeBase58(const char* psz, std::vector<unsigned char>& vch)
psz++; psz++;
// Skip and count leading '1's. // Skip and count leading '1's.
int zeroes = 0; int zeroes = 0;
int length = 0;
while (*psz == '1') { while (*psz == '1') {
zeroes++; zeroes++;
psz++; psz++;
} }
// Allocate enough space in big-endian base256 representation. // Allocate enough space in big-endian base256 representation.
std::vector<unsigned char> b256(strlen(psz) * 733 / 1000 + 1); // log(58) / log(256), rounded up. int size = strlen(psz) * 733 /1000 + 1; // log(58) / log(256), rounded up.
std::vector<unsigned char> b256(size);
// Process the characters. // Process the characters.
while (*psz && !isspace(*psz)) { while (*psz && !isspace(*psz)) {
// Decode base58 character // Decode base58 character
@ -39,12 +41,14 @@ bool DecodeBase58(const char* psz, std::vector<unsigned char>& vch)
return false; return false;
// Apply "b256 = b256 * 58 + ch". // Apply "b256 = b256 * 58 + ch".
int carry = ch - pszBase58; int carry = ch - pszBase58;
for (std::vector<unsigned char>::reverse_iterator it = b256.rbegin(); it != b256.rend(); it++) { int i = 0;
for (std::vector<unsigned char>::reverse_iterator it = b256.rbegin(); (carry != 0 || i < length) && (it != b256.rend()); ++it, ++i) {
carry += 58 * (*it); carry += 58 * (*it);
*it = carry % 256; *it = carry % 256;
carry /= 256; carry /= 256;
} }
assert(carry == 0); assert(carry == 0);
length = i;
psz++; psz++;
} }
// Skip trailing spaces. // Skip trailing spaces.
@ -53,7 +57,7 @@ bool DecodeBase58(const char* psz, std::vector<unsigned char>& vch)
if (*psz != 0) if (*psz != 0)
return false; return false;
// Skip leading zeroes in b256. // Skip leading zeroes in b256.
std::vector<unsigned char>::iterator it = b256.begin(); std::vector<unsigned char>::iterator it = b256.begin() + (size - length);
while (it != b256.end() && *it == 0) while (it != b256.end() && *it == 0)
it++; it++;
// Copy result into output vector. // Copy result into output vector.