feat(baseN): encode

This commit is contained in:
2024-09-18 21:38:06 +03:00
parent 5a42cf1011
commit 61c0ae3a72
2 changed files with 68 additions and 132 deletions

View File

@ -31,123 +31,57 @@ namespace baseN
{ {
return str.size() * std::log(base) / log256 + 1; return str.size() * std::log(base) / log256 + 1;
} }
// 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, uint64_t str_size, uint8_t base, const char *digits)
// { {
// if (data_size == 0) std::vector<uint8_t> dv(std::find_if(data, data + data_size, [](uint8_t item)
// { { return item != 0; }),
// return; data + data_size);
// } if (dv.size() == 0)
// char res_str[enc_size]; {
// uint8_t div_buf[data_size]; return;
// std::copy(data, data + data_size, div_buf); }
// int64_t std::span<char> sv(str, str_size);
// zero_count = 0, auto sv_it = sv.rbegin();
// idx_div = 0, auto dv_it = dv.begin();
// idx_quo = 0, auto quo_it = dv.begin();
// idx_quo_last = data_size, auto quo_it_last = dv.end();
// idx_str = enc_size - 1; uint16_t div = *dv_it++;
// uint16_t div = data[idx_div++];
while ((dv[0] > base || quo_it_last > dv.begin() + 1) && sv_it < sv.rend() - 1)
// while (zero_count < (int64_t)data_size && data[zero_count] == 0) {
// { if (div < base)
// zero_count++; {
// } div <<= 8;
// while (idx_quo_last > 1 || div_buf[0] > base) div += *dv_it++;
// { }
// if (div < base) *quo_it++ = div / base;
// { div %= base;
// div <<= 8; while (dv_it < quo_it_last)
// div += div_buf[idx_div++]; {
// } div <<= 8;
// div_buf[idx_quo++] = div / base; div += *dv_it++;
// div %= base; *quo_it++ = div / base;
// while (idx_div < idx_quo_last) div %= base;
// { }
// div <<= 8; quo_it_last = quo_it;
// div += div_buf[idx_div++]; dv_it = dv.begin();
// div_buf[idx_quo++] = div / base; quo_it = dv.begin();
// div %= base; *sv_it++ = digits[div];
// } div = *dv_it++;
// idx_quo_last = idx_quo; }
// idx_quo = 0; *sv_it++ = digits[div];
// idx_div = 0; for (uint64_t i = 0; i < data_size - dv.size() && sv_it < sv.rend(); i++)
// res_str[idx_str--] = digits[div]; {
// div = div_buf[idx_div++]; *sv_it++ = digits[0];
// } }
// res_str[idx_str--] = digits[div]; }
// while (zero_count > 0 && idx_str >= 0) std::string encode(std::span<const uint8_t> data, uint8_t base, const char *digits) noexcept
// { {
// res_str[idx_str--] = digits[0]; std::string str(baseN::sizeEncoded(data, base), ' ');
// zero_count--; baseN::encode(data.data(), data.size(), str.data(), str.size(), base, digits);
// } str.erase(str.begin(), std::find_if(
// while (idx_str >= 0) str.begin(), str.end(), [](char ch)
// { { return ch != ' '; }));
// res_str[idx_str--] = ' '; return str;
// } }
// std::copy(res_str, res_str + enc_size, str);
// }
// std::string encode(std::span<const uint8_t> data, uint8_t base, const char *digits, uint64_t enc_size) noexcept
// {
// std::string str(enc_size, ' ');
// baseN::encode(data.data(), data.size(), str.data(), base, digits, enc_size);
// str.erase(str.begin(), std::find_if(
// str.begin(), str.end(), [](char ch)
// { return ch != ' '; }));
// return str;
// }
// std::string encode(std::span<const uint8_t> data, uint8_t base, const char *digits) noexcept
// {
// 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 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] != '\0' && 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<uint8_t> decode(std::string_view str, uint8_t base, const char *digits, const int8_t *map, uint64_t dec_size)
// {
// std::vector<uint8_t> 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<uint8_t> decode(std::string_view 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);
// }
} }

View File

@ -32,19 +32,21 @@ TEST(baseN, isValid)
EXPECT_EQ(true, isValid("123", b58map)); EXPECT_EQ(true, isValid("123", b58map));
EXPECT_EQ(false, isValid("@#$", b58map)); EXPECT_EQ(false, isValid("@#$", b58map));
} }
// TEST(baseN, encode) TEST(baseN, encode)
// { {
// EXPECT_EQ("Ky", encode(hex::decode("044c"), 58, b58digits)); EXPECT_EQ("", encode(hex::decode(""), 58, b58digits));
// EXPECT_EQ("KyK", encode(hex::decode("f94a"), 58, b58digits)); EXPECT_EQ("Ky", encode(hex::decode("044c"), 58, b58digits));
// EXPECT_EQ("KyKX", encode(hex::decode("387ae2"), 58, b58digits)); EXPECT_EQ("KyK", encode(hex::decode("f94a"), 58, b58digits));
// EXPECT_EQ("KyKXa", encode(hex::decode("0ccbd755"), 58, b58digits)); EXPECT_EQ("KyKX", encode(hex::decode("387ae2"), 58, b58digits));
// EXPECT_EQ("KyKXaa", encode(hex::decode("02e62ec963"), 58, b58digits)); EXPECT_EQ("KyKXa", encode(hex::decode("0ccbd755"), 58, b58digits));
// } EXPECT_EQ("KyKXaa", encode(hex::decode("02e62ec963"), 58, b58digits));
// TEST(baseN, encode_1e3) }
// { TEST(baseN, encode_1e3)
// std::vector<uint8_t> data(1e3); {
// encode(data, 58, b58digits, data.size() * 138 / 100 + 1); std::vector<uint8_t> data(1e3);
// } std::fill(data.begin(), data.end(), 1);
encode(data, 58, b58digits);
}
// TEST(baseN, decode) // TEST(baseN, decode)
// { // {
// EXPECT_EQ(hex::encode(decode("Ky", 58, b58digits, b58map)), "044c"); // EXPECT_EQ(hex::encode(decode("Ky", 58, b58digits, b58map)), "044c");