diff --git a/include/base/baseN.hpp b/include/base/baseN.hpp index fe3c15b..db85d13 100644 --- a/include/base/baseN.hpp +++ b/include/base/baseN.hpp @@ -10,12 +10,10 @@ namespace baseN bool isValid(const std::string &str, const int8_t *map) noexcept; void encode(const uint8_t *data, uint64_t data_size, char *str, uint8_t base, const char *digits, uint64_t enc_size) noexcept; - void encode(const uint8_t *data, uint64_t data_size, char *str, uint8_t base, const char *digits) noexcept; std::string encode(std::vector data, uint8_t base, const char *digits, uint64_t enc_size) noexcept; std::string encode(std::vector data, uint8_t base, const char *digits) noexcept; - void decode(const char *str, uint8_t *data, uint64_t data_size, uint8_t base, const char *digits, const char *map, uint64_t dec_size); - void decode(const char *str, uint8_t *data, uint64_t data_size, uint8_t base, const char *digits, const char *map); - std::vector decode(const std::string &str, uint8_t base, const char *digits, const char *map, uint64_t dec_size); - std::vector decode(const std::string &str, uint8_t base, const char *digits, const char *map); + void decode(const char *str, uint8_t *data, uint64_t data_size, uint8_t base, const char *digits, const int8_t *map, uint64_t dec_size); + std::vector decode(const std::string &str, uint8_t base, const char *digits, const int8_t *map, uint64_t dec_size); + std::vector decode(const std::string &str, uint8_t base, const char *digits, const int8_t *map); } \ No newline at end of file diff --git a/src/baseN.cpp b/src/baseN.cpp index 0fa1d4c..8308744 100644 --- a/src/baseN.cpp +++ b/src/baseN.cpp @@ -79,10 +79,6 @@ namespace baseN } std::copy(res_str, res_str + enc_size, str); } - void encode(const uint8_t *data, uint64_t data_size, char *str, uint8_t base, const char *digits) noexcept - { - baseN::encode(data, data_size, str, base, digits, data_size * std::log(256) / std::log(base) + 1); - } std::string encode(std::vector data, uint8_t base, const char *digits, uint64_t enc_size) noexcept { std::string str(enc_size, ' '); @@ -99,51 +95,57 @@ namespace baseN return baseN::encode(data, base, digits, data.size() * std::log(256) / std::log(base) + 1); } - // void decode(const char *str, uint8_t *data, uint64_t data_size, uint8_t base, const char *digits, const char *map, uint64_t dec_size) - // { - // if (str[0] == '\0') - // { - // return; - // } - // if (!baseN::isValid(str, map)) - // { - // throw std::logic_error("baseN::decode: out of digits map"); - // } - // uint8_t *res_data = new uint8_t[dec_size]; - // uint64_t idx_str = 0; - // int64_t - // zero_count = 0, - // idx_quo = dec_size - 1, - // idx_quo_last = dec_size - 2; - // uint16_t div; + void decode(const char *str, uint8_t *data, uint64_t data_size, uint8_t base, const char *digits, const int8_t *map, uint64_t dec_size) + { + if (str[0] == '\0') + { + return; + } + if (!baseN::isValid(str, map)) + { + throw std::logic_error("baseN::decode: out of digits map"); + } + uint8_t res_data[dec_size]; + uint64_t idx_str = 0; + int64_t + zero_count = 0, + idx_quo = dec_size - 1, + idx_quo_last = dec_size - 2; + uint16_t div; - // while (str[zero_count] == digits[0]) - // { - // zero_count++; - // } - // res_data[idx_quo] = map[(int8_t)str[idx_str++]]; - // while (idx_str < str.size()) - // { - // div = map[(int8_t)str[idx_str++]]; - // while (idx_quo > idx_quo_last && idx_quo > 0) - // { - // div += data[idx_quo] * base; - // data[idx_quo--] = div; - // div >>= 8; - // } - // data[idx_quo--] = div; - // idx_quo_last = idx_quo; - // idx_quo = data.size() - 1; - // } - // idx_quo = 0; - // while (data[idx_quo] == 0) - // { - // idx_quo++; - // } - // data.erase(data.begin(), data.begin() + idx_quo - zero_count); - // delete[] res_data; - // } - // void decode(const char *str, uint8_t *data, uint64_t data_size, uint8_t base, const char *digits, const char *map); - // std::vector decode(const std::string &str, uint8_t base, const char *digits, const char *map, uint64_t dec_size); - // std::vector decode(const std::string &str, uint8_t base, const char *digits, const char *map); + while (str[zero_count] == digits[0]) + { + zero_count++; + } + res_data[idx_quo] = map[(int8_t)str[idx_str++]]; + while (str[idx_str] != '\0') + { + div = map[(int8_t)str[idx_str++]]; + while (idx_quo > idx_quo_last && idx_quo > 0) + { + div += res_data[idx_quo] * base; + res_data[idx_quo--] = div; + div >>= 8; + } + res_data[idx_quo--] = div; + idx_quo_last = idx_quo; + idx_quo = dec_size - 1; + } + std::copy(res_data, res_data + std::min(dec_size, data_size), data); + } + std::vector decode(const std::string &str, uint8_t base, const char *digits, const int8_t *map, uint64_t dec_size) + { + std::vector data(dec_size); + baseN::decode(str.data(), data.data(), data.size(), base, digits, map, dec_size); + data.erase(data.begin(), std::find_if( + data.begin(), data.end(), [](uint8_t byte){ + return byte != 0; + }) + ); + return data; + } + std::vector decode(const std::string &str, uint8_t base, const char *digits, const int8_t *map) + { + return baseN::decode(str, base, digits, map, str.size() * std::log(base) / std::log(256) + 1); + } } \ No newline at end of file diff --git a/test/test-baseN.cpp b/test/test-baseN.cpp index d541762..a73add7 100644 --- a/test/test-baseN.cpp +++ b/test/test-baseN.cpp @@ -44,14 +44,14 @@ TEST(baseN, encode) // std::vector data(1e6); // encode(data); // } -// TEST(baseN, decode) -// { -// EXPECT_EQ(btc::data::hex::encode(decode("Ky")), "044c"); -// EXPECT_EQ(btc::data::hex::encode(decode("KyK")), "f94a"); -// EXPECT_EQ(btc::data::hex::encode(decode("KyKX")), "387ae2"); -// EXPECT_EQ(btc::data::hex::encode(decode("KyKXa")), "0ccbd755"); -// EXPECT_EQ(btc::data::hex::encode(decode("KyKXaa")), "02e62ec963"); -// } +TEST(baseN, decode) +{ + EXPECT_EQ(hex::encode(decode("Ky", 58, b58digits, b58map)), "044c"); + EXPECT_EQ(hex::encode(decode("KyK", 58, b58digits, b58map)), "f94a"); + EXPECT_EQ(hex::encode(decode("KyKX", 58, b58digits, b58map)), "387ae2"); + EXPECT_EQ(hex::encode(decode("KyKXa", 58, b58digits, b58map)), "0ccbd755"); + EXPECT_EQ(hex::encode(decode("KyKXaa", 58, b58digits, b58map)), "02e62ec963"); +} // TEST(baseN, decode_1e6) // { // std::string str(1e6, '0');