Changeset View
Changeset View
Standalone View
Standalone View
src/base58.cpp
// Copyright (c) 2014-2016 The Bitcoin Core developers | // Copyright (c) 2014-2016 The Bitcoin Core developers | ||||
// Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
#include "base58.h" | #include "base58.h" | ||||
#include "hash.h" | #include "hash.h" | ||||
#include "script/script.h" | #include "script/script.h" | ||||
#include "uint256.h" | #include "uint256.h" | ||||
#include "utilstrencodings.h" | |||||
#include <boost/variant/apply_visitor.hpp> | #include <boost/variant/apply_visitor.hpp> | ||||
#include <boost/variant/static_visitor.hpp> | #include <boost/variant/static_visitor.hpp> | ||||
#include <cassert> | #include <cassert> | ||||
#include <cstdint> | #include <cstdint> | ||||
#include <cstring> | #include <cstring> | ||||
#include <string> | #include <string> | ||||
#include <vector> | #include <vector> | ||||
/** All alphanumeric characters except for "0", "I", "O", and "l" */ | /** All alphanumeric characters except for "0", "I", "O", and "l" */ | ||||
static const char *pszBase58 = | static const char *pszBase58 = | ||||
"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; | "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; | ||||
bool DecodeBase58(const char *psz, std::vector<uint8_t> &vch) { | bool DecodeBase58(const char *psz, std::vector<uint8_t> &vch) { | ||||
// Skip leading spaces. | // Skip leading spaces. | ||||
while (*psz && isspace(*psz)) { | while (*psz && IsSpace(*psz)) { | ||||
psz++; | psz++; | ||||
} | } | ||||
// Skip and count leading '1's. | // Skip and count leading '1's. | ||||
int zeroes = 0; | int zeroes = 0; | ||||
int length = 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. | ||||
// log(58) / log(256), rounded up. | // log(58) / log(256), rounded up. | ||||
int size = strlen(psz) * 733 / 1000 + 1; | int size = strlen(psz) * 733 / 1000 + 1; | ||||
std::vector<uint8_t> b256(size); | std::vector<uint8_t> b256(size); | ||||
// Process the characters. | // Process the characters. | ||||
while (*psz && !isspace(*psz)) { | while (*psz && !IsSpace(*psz)) { | ||||
// Decode base58 character | // Decode base58 character | ||||
const char *ch = strchr(pszBase58, *psz); | const char *ch = strchr(pszBase58, *psz); | ||||
if (ch == nullptr) { | if (ch == nullptr) { | ||||
return false; | return false; | ||||
} | } | ||||
// Apply "b256 = b256 * 58 + ch". | // Apply "b256 = b256 * 58 + ch". | ||||
int carry = ch - pszBase58; | int carry = ch - pszBase58; | ||||
int i = 0; | int i = 0; | ||||
for (std::vector<uint8_t>::reverse_iterator it = b256.rbegin(); | for (std::vector<uint8_t>::reverse_iterator it = b256.rbegin(); | ||||
(carry != 0 || i < length) && (it != b256.rend()); ++it, ++i) { | (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; | length = i; | ||||
psz++; | psz++; | ||||
} | } | ||||
// Skip trailing spaces. | // Skip trailing spaces. | ||||
while (isspace(*psz)) { | while (IsSpace(*psz)) { | ||||
psz++; | psz++; | ||||
} | } | ||||
if (*psz != 0) { | if (*psz != 0) { | ||||
return false; | return false; | ||||
} | } | ||||
// Skip leading zeroes in b256. | // Skip leading zeroes in b256. | ||||
std::vector<uint8_t>::iterator it = b256.begin() + (size - length); | std::vector<uint8_t>::iterator it = b256.begin() + (size - length); | ||||
while (it != b256.end() && *it == 0) | while (it != b256.end() && *it == 0) | ||||
▲ Show 20 Lines • Show All 234 Lines • Show Last 20 Lines |