20 #include <ripple/basics/safe_cast.h>
21 #include <ripple/protocol/digest.h>
22 #include <ripple/protocol/tokens.h>
23 #include <boost/container/small_vector.hpp>
34 "rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz";
37 "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
41 template <
class Hasher>
42 static typename Hasher::result_type
47 return static_cast<typename Hasher::result_type
>(h);
55 static typename Hasher::result_type
58 return digest<Hasher>(v.
data(), v.
size());
62 template <
class Hasher,
class... Args>
63 static typename Hasher::result_type
66 return digest<Hasher>(digest<Hasher>(args...));
81 auto const h = digest2<sha256_hasher>(message, size);
103 char const*
const alphabet)
105 auto pbegin =
reinterpret_cast<unsigned char const*
>(message);
106 auto const pend = pbegin + size;
110 while (pbegin != pend && *pbegin == 0)
116 auto const b58begin =
reinterpret_cast<unsigned char*
>(temp);
117 auto const b58end = b58begin + temp_size;
121 while (pbegin != pend)
125 for (
auto iter = b58end; iter != b58begin; --iter)
127 carry += 256 * (iter[-1]);
128 iter[-1] = carry % 58;
136 auto iter = b58begin;
137 while (iter != b58end && *iter == 0)
142 str.
reserve(zeroes + (b58end - iter));
143 str.
assign(zeroes, alphabet[0]);
144 while (iter != b58end)
145 str += alphabet[*(iter++)];
154 char const*
const alphabet)
157 auto const expanded = 1 + size + 4;
162 auto const bufsize = expanded * 3;
164 boost::container::small_vector<std::uint8_t, 1024> buf(bufsize);
168 buf[0] = safe_cast<std::underlying_type_t<TokenType>>(type);
171 checksum(buf.data() + 1 + size, buf.data(), 1 + size);
176 buf.data() + expanded,
201 template <
class InverseArray>
205 auto psz = s.
c_str();
206 auto remain = s.
size();
209 while (remain > 0 && inv[*psz] == 0)
224 auto carry = inv[*psz];
228 for (
auto iter = b256.
rbegin(); iter != b256.
rend(); ++iter)
240 b256.
begin(), b256.
end(), [](
unsigned char c) { return c != 0; });
243 result.
assign(zeroes, 0x00);
244 while (iter != b256.
end())
254 template <
class InverseArray>
265 if (type != safe_cast<TokenType>(
static_cast<std::uint8_t>(ret[0])))
291 for (
auto const c : digits)
292 map_[
static_cast<unsigned char>(c)] = i++;
298 return map_[
static_cast<unsigned char>(c)];
static std::string decodeBase58(std::string const &s, InverseArray const &inv)
static InverseAlphabet bitcoinInverse(bitcoinAlphabet)
std::string base58EncodeToken(TokenType type, void const *token, std::size_t size)
static InverseAlphabet rippleInverse(rippleAlphabet)
InverseAlphabet(std::string const &digits)
static Hasher::result_type digest(void const *data, std::size_t size) noexcept
static char bitcoinAlphabet[]
std::string base58EncodeTokenBitcoin(TokenType type, void const *token, std::size_t size)
static Hasher::result_type digest2(Args const &... args)
std::array< int, 256 > map_
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
static char rippleAlphabet[]
int operator[](char c) const
static std::string encodeBase58(void const *message, std::size_t size, void *temp, std::size_t temp_size, char const *const alphabet)
static std::string decodeBase58Token(std::string const &s, TokenType type, InverseArray const &inv)
void checksum(void *out, void const *message, std::size_t size)
std::string decodeBase58TokenBitcoin(std::string const &s, TokenType type)
Decode a Base58 token using Bitcoin alphabet.
static std::string encodeToken(TokenType type, void const *token, std::size_t size, char const *const alphabet)