mirror of
https://github.com/eosswedenorg/libantelope
synced 2026-06-16 03:34:56 +02:00
include/libeosio/base58.hpp: adding base58_decode functions.
This commit is contained in:
parent
a43b913277
commit
ed59959b5b
4 changed files with 136 additions and 0 deletions
|
|
@ -36,6 +36,13 @@ std::string base58_encode(const std::string& str);
|
|||
std::string base58_encode(const std::vector<unsigned char>& vch);
|
||||
std::string base58_encode(const unsigned char* pbegin, const unsigned char* pend);
|
||||
|
||||
|
||||
/**
|
||||
* Base58 Decoding functions.
|
||||
*/
|
||||
bool base58_decode(const char* psz, std::string& out);
|
||||
bool base58_decode(const std::string& str, std::string& out);
|
||||
|
||||
/**
|
||||
* Returns true if `ch` is a base58 character, false otherwise.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -27,11 +27,35 @@
|
|||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <libeosio/base58.hpp>
|
||||
|
||||
namespace libeosio {
|
||||
|
||||
static const char charmap[59] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
||||
static const int8_t table[256] = {
|
||||
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8,-1,-1,-1,-1,-1,-1,
|
||||
-1, 9,10,11,12,13,14,15, 16,-1,17,18,19,20,21,-1,
|
||||
22,23,24,25,26,27,28,29, 30,31,32,-1,-1,-1,-1,-1,
|
||||
-1,33,34,35,36,37,38,39, 40,41,42,43,-1,44,45,46,
|
||||
47,48,49,50,51,52,53,54, 55,56,57,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
|
||||
};
|
||||
|
||||
bool is_space(char c) {
|
||||
return c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v';
|
||||
}
|
||||
|
||||
|
||||
std::string base58_encode(const unsigned char* pbegin, const unsigned char* pend) {
|
||||
|
||||
|
|
@ -84,6 +108,62 @@ std::string base58_encode(const std::vector<unsigned char>& vch) {
|
|||
return base58_encode(vch.data(), vch.data() + vch.size());
|
||||
}
|
||||
|
||||
bool base58_decode(const char* psz, std::string& out) {
|
||||
// Skip leading spaces.
|
||||
while (*psz && is_space(*psz))
|
||||
psz++;
|
||||
// Skip and count leading '1's.
|
||||
int zeroes = 0;
|
||||
int length = 0;
|
||||
while (*psz == '1') {
|
||||
zeroes++;
|
||||
psz++;
|
||||
}
|
||||
// Allocate enough space in big-endian base256 representation.
|
||||
int size = strlen(psz) * 733 /1000 + 1; // log(58) / log(256), rounded up.
|
||||
std::vector<unsigned char> b256(size);
|
||||
// Process the characters.
|
||||
|
||||
while (*psz && !is_space(*psz)) {
|
||||
// Decode base58 character
|
||||
int carry = table[(uint8_t)*psz];
|
||||
if (carry == -1) // Invalid b58 character
|
||||
return false;
|
||||
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);
|
||||
*it = carry % 256;
|
||||
carry /= 256;
|
||||
}
|
||||
assert(carry == 0);
|
||||
length = i;
|
||||
psz++;
|
||||
}
|
||||
|
||||
// Skip trailing spaces.
|
||||
while (is_space(*psz))
|
||||
psz++;
|
||||
|
||||
if (*psz != 0)
|
||||
return false;
|
||||
|
||||
// Skip leading zeroes in b256.
|
||||
std::vector<unsigned char>::iterator it = b256.begin() + (size - length);
|
||||
while (it != b256.end() && *it == 0)
|
||||
it++;
|
||||
|
||||
// Copy result into output vector.
|
||||
out.reserve(zeroes + (b256.end() - it));
|
||||
out.assign(zeroes, 0);
|
||||
while (it != b256.end())
|
||||
out.push_back(*(it++));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool base58_decode(const std::string& str, std::string& out) {
|
||||
return base58_decode(str.c_str(), out);
|
||||
}
|
||||
|
||||
bool is_base58(char ch) {
|
||||
for(unsigned int i=0; i < sizeof(charmap); i++) {
|
||||
if (ch == charmap[i]) {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ set(TEST_SRC
|
|||
|
||||
# Base58
|
||||
base58/encode.cpp
|
||||
base58/decode.cpp
|
||||
base58/is_base58.cpp
|
||||
|
||||
# WIF
|
||||
|
|
|
|||
48
tests/base58/decode.cpp
Normal file
48
tests/base58/decode.cpp
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
#include <libeosio/base58.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <doctest.h>
|
||||
|
||||
typedef struct {
|
||||
std::string name;
|
||||
std::string in;
|
||||
std::string expectedOut;
|
||||
bool expectedReturn;
|
||||
} test_t;
|
||||
|
||||
typedef std::vector<test_t> tests;
|
||||
|
||||
TEST_CASE("base58_decode") {
|
||||
tests input = {
|
||||
test_t{"empty", "","", true},
|
||||
test_t{"invalid","OI","",false},
|
||||
test_t{
|
||||
"valid #1",
|
||||
"2nPTv2DT874jRaYBN4uhM9mT2iRiwdJuCXuX5buUHyyvWUSu6cX62i8HYo8PsWqgs9DHbwhpSpV5SVUnCqyLcpxcuGanH68eXgzZTGq",
|
||||
"Quisque ut ipsum lorem. Nullam ac justo elit. Sed gravida convallis mattis.",
|
||||
true
|
||||
},
|
||||
test_t{
|
||||
"valid #2",
|
||||
"5yAgp6rBagDHQZ3GacZSeaEPF2jfuwVHM21aNfXETJgn3EkArxc5UWSq1RM",
|
||||
"Cras fringilla, eros et imperdiet tincidunt",
|
||||
true
|
||||
},
|
||||
test_t{
|
||||
"valid #3",
|
||||
"9P7SxYWTWMq5hHkri53b1CGvWKRXxq3uXWPs5RiVtYagFrsnTXDxvKnk1twkPmV7BuxcRhBHWSwFLXpXbmdfHwZrnDaTB3wrBhsjm2Dd7F95ixh5vQLxajmT8hd22yUbvXuAZci8vTgFWMUyQi5YzWwntQiK5KFDkx3oA7kxvdU5t1yJZur84a9aKTCihEWtvCJ6LoBCpxvyB16YaCKeBQWLbUqoaXvFoDM78BpKD8biYyWQhnzHonjdwAS4KNXs5ByBdBvvPK1Q2Knr8zuFZxKHEFmgZGFTt8SMSsTDjkanUjojbfpJt5gcrHh6UFrt45n7kT9sj9Xsf1UyXZG3E2H85jXSbVnKowz2VPq1TkLLUKG8CSfdH3fVRp2E3yL5cpbbFWngbMzsbBZDgr4kPPcazebvSZ8qm8taBcBmt1ry25ey9TfFbMzP4FR1q9yjvkqGusMtrrBFm8YEeRmoMugMQoXvUgpExh29j",
|
||||
"Praesent massa nibh, feugiat ac aliquet sed, varius quis metus. Fusce auctor imperdiet purus. Vivamus elementum risus vel imperdiet condimentum. Nunc iaculis, sem eu sollicitudin tempus, nibh felis scelerisque orci, a tincidunt felis lectus in nulla. Vestibulum egestas eu elit id luctus. Vivamus eget ipsum neque. Fusce eleifend mauris a tempus vehicula.",
|
||||
true
|
||||
},
|
||||
};
|
||||
|
||||
for(tests::const_iterator it = input.begin(); it != input.end(); it++) {
|
||||
|
||||
SUBCASE(it->name.c_str()) {
|
||||
std::string result;
|
||||
|
||||
CHECK( libeosio::base58_decode(it->in, result) == it->expectedReturn );
|
||||
CHECK( result == it->expectedOut );
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue