feat(base64): encode
This commit is contained in:
@ -7,12 +7,12 @@
|
|||||||
|
|
||||||
namespace base64
|
namespace base64
|
||||||
{
|
{
|
||||||
bool isValid(const char *str) noexcept;
|
bool isValid(const char *str, size_t str_size) noexcept;
|
||||||
bool isValid(std::string_view str) noexcept;
|
bool isValid(std::string_view str) noexcept;
|
||||||
|
|
||||||
void encode(const uint8_t *data, uint64_t data_size, char *str) noexcept;
|
void encode(const uint8_t *data, size_t data_size, char *str, size_t str_size);
|
||||||
std::string encode(std::span<const uint8_t> data) noexcept;
|
std::string encode(std::span<const uint8_t> data) noexcept;
|
||||||
|
|
||||||
void decode(const char *str, uint8_t *data, uint64_t data_size);
|
void decode(const char *str, size_t str_size, uint8_t *data, size_t data_size);
|
||||||
std::vector<uint8_t> decode(std::string_view str);
|
std::vector<uint8_t> decode(std::string_view str) noexcept;
|
||||||
}
|
}
|
||||||
@ -29,9 +29,9 @@ static const int8_t b64map[] = {
|
|||||||
|
|
||||||
namespace base64
|
namespace base64
|
||||||
{
|
{
|
||||||
bool isValid(const char *str) noexcept
|
bool isValid(const char *str, size_t str_size) noexcept
|
||||||
{
|
{
|
||||||
return base64::isValid(std::string_view(str));
|
return base64::isValid(std::string_view(str, str_size));
|
||||||
}
|
}
|
||||||
bool isValid(std::string_view str) noexcept
|
bool isValid(std::string_view str) noexcept
|
||||||
{
|
{
|
||||||
@ -44,12 +44,47 @@ namespace base64
|
|||||||
}
|
}
|
||||||
return baseN::isValid(sv, b64map);
|
return baseN::isValid(sv, b64map);
|
||||||
}
|
}
|
||||||
// void encode(const uint8_t *data, uint64_t data_size, char *str) noexcept
|
void encode(const uint8_t *data, size_t data_size, char *str, size_t str_size)
|
||||||
// {
|
{
|
||||||
// }
|
if (str_size < data_size / 3 * 4 + (data_size % 3 ? 4 : 0))
|
||||||
// std::string encode(std::span<const uint8_t> data) noexcept
|
{
|
||||||
// {
|
throw std::logic_error("base64::encode: not enough allocated length");
|
||||||
// }
|
}
|
||||||
|
for (size_t i = 0; i < data_size / 3; i++)
|
||||||
|
{
|
||||||
|
str[i * 4] = b64digits[data[i * 3] >> 2];
|
||||||
|
str[i * 4 + 1] = b64digits[(data[i * 3] << 4 | data[i * 3 + 1] >> 4) & 0x3F];
|
||||||
|
str[i * 4 + 2] = b64digits[(data[i * 3 + 1] << 2 | data[i * 3 + 2] >> 6) & 0x3F];
|
||||||
|
str[i * 4 + 3] = b64digits[data[i * 3 + 2] & 0x3F];
|
||||||
|
}
|
||||||
|
uint64_t last_idx = data_size / 3 * 4;
|
||||||
|
if (last_idx + 3 < str_size)
|
||||||
|
{
|
||||||
|
switch (data_size % 3)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
str[last_idx] = b64digits[data[data_size - 1] >> 2];
|
||||||
|
str[last_idx + 1] = b64digits[data[data_size - 1] << 4 & 0x30];
|
||||||
|
str[last_idx + 2] = '=';
|
||||||
|
str[last_idx + 3] = '=';
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
str[last_idx] = b64digits[data[data_size - 2] >> 2];
|
||||||
|
str[last_idx + 1] = b64digits[(data[data_size - 2] << 4 | data[data_size - 1] >> 4) & 0x3F];
|
||||||
|
str[last_idx + 2] = b64digits[data[data_size - 1] & 0x0F];
|
||||||
|
str[last_idx + 3] = '=';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::string encode(std::span<const uint8_t> data) noexcept
|
||||||
|
{
|
||||||
|
std::string str(data.size() / 3 * 4 + (data.size() % 3 ? 4 : 0), ' ');
|
||||||
|
base64::encode(data.data(), data.size(), str.data(), str.size());
|
||||||
|
return str;
|
||||||
|
}
|
||||||
// void decode(const char *str, uint8_t *data, uint64_t data_size)
|
// void decode(const char *str, uint8_t *data, uint64_t data_size)
|
||||||
// {
|
// {
|
||||||
// }
|
// }
|
||||||
|
|||||||
@ -13,14 +13,18 @@ TEST(base64, isValid)
|
|||||||
EXPECT_FALSE(isValid("1==="));
|
EXPECT_FALSE(isValid("1==="));
|
||||||
EXPECT_FALSE(isValid("?!*"));
|
EXPECT_FALSE(isValid("?!*"));
|
||||||
}
|
}
|
||||||
// TEST(base64, encode)
|
TEST(base64, encode)
|
||||||
// {
|
{
|
||||||
// }
|
EXPECT_EQ(encode(hex::decode("")), "");
|
||||||
// TEST(base64, encode_1e6)
|
EXPECT_EQ(encode(hex::decode("04a504a5")), "BKUEpQ==");
|
||||||
// {
|
EXPECT_EQ(encode(hex::decode("04a504a500")), "BKUEpQA=");
|
||||||
// std::vector<uint8_t> data(1e6);
|
EXPECT_EQ(encode(hex::decode("04a504a50000")), "BKUEpQAA");
|
||||||
// encode(data);
|
}
|
||||||
// }
|
TEST(base64, encode_1e7)
|
||||||
|
{
|
||||||
|
std::vector<uint8_t> data(1e7);
|
||||||
|
encode(data);
|
||||||
|
}
|
||||||
// TEST(base64, decode)
|
// TEST(base64, decode)
|
||||||
// {
|
// {
|
||||||
// }
|
// }
|
||||||
|
|||||||
Reference in New Issue
Block a user