21 const std::string base64_itoa_map =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
22 const std::string crypt64_itoa_map =
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
24 void fill_atoi_map(std::vector<int>& atoi,
const std::string& itoa)
26 for(
int i=0;
i<64; ++
i) {
31 const std::vector<int>& base64_atoi_map()
33 static std::vector<int> atoi64(256, -1);
34 if(atoi64[
'A'] == -1) {
35 fill_atoi_map(atoi64, base64_itoa_map);
39 const std::vector<int>& crypt64_atoi_map()
41 static std::vector<int> atoi64(256, -1);
42 if(atoi64[
'A'] == -1) {
43 fill_atoi_map(atoi64, crypt64_itoa_map);
47 char itoa(
unsigned value,
const std::string& map)
49 return map[value & 0x3f];
52 std::vector<uint8_t> generic_decode_be(std::string_view
in,
const std::vector<int>& atoi_map)
54 const std::size_t last_char =
in.find_last_not_of(
"=");
55 if(last_char == std::string::npos) {
58 const std::size_t num_chars = last_char + 1;
59 const std::size_t length = num_chars * 6 / 8;
61 std::vector<uint8_t> out;
64 int val = 0, bits = -8;
65 for(
unsigned char c:
in) {
66 if(atoi_map[
c] == -1) {
74 val = (val<<6) + atoi_map[
c];
77 out.push_back(
static_cast<char>((val >> bits) & 0xFF));
82 if(out.size() != length) {
89 std::vector<uint8_t> generic_decode_le(std::string_view
in,
const std::vector<int>& atoi_map)
91 const std::size_t last_char =
in.find_last_not_of(
"=");
92 if(last_char == std::string::npos) {
95 const std::size_t length = last_char * 6 / 8;
97 std::vector<uint8_t> out;
100 for(std::size_t
i = 0;
i <= last_char;
i += 4) {
102 unsigned value = atoi_map[
in[
i]];
104 const bool second_char =
i + 1 <= last_char;
109 value |= atoi_map[
in[
i+1]] << 6;
112 out.push_back(value & 0xFF);
114 const bool third_char =
i + 2 <= last_char;
119 value |= atoi_map[
in[
i+2]] << 12;
122 out.push_back((value >> 8) & 0xFF);
124 const bool fourth_char =
i + 3 <= last_char;
129 value |= atoi_map[
in[
i+3]] << 18;
132 out.push_back((value >> 16) & 0xFF);
140 const int in_len =
in.length();
141 const int groups = (in_len + 2) / 3;
142 const int out_len = groups * 4;
147 out.reserve(out_len);
156 out.push_back(itoa(value >> bits, itoa_map));
160 out.push_back(itoa(value << (6 - bits), itoa_map));
165 out.resize(out_len,
'=');
173 const int in_len =
in.length();
174 const int groups = (in_len + 2) / 3;
175 const int out_len = groups * 4;
180 out.reserve(out_len);
183 unsigned value =
in[
i];
185 out.push_back(itoa(value, itoa_map));
187 const bool second_byte = ++
i < in_len;
189 value |=
static_cast<int>(
in[
i]) << 8;
192 out.push_back(itoa(value >> 6, itoa_map));
197 const bool third_byte = ++
i < in_len;
199 value |=
static_cast<int>(
in[
i]) << 16;
202 out.push_back(itoa(value >> 12, itoa_map));
205 out.push_back(itoa(value >> 18, itoa_map));
212 out.resize(out_len,
'=');
223 return generic_decode_be(
in, base64_atoi_map());
227 return generic_encode_be(bytes, base64_itoa_map,
true);
233 return generic_decode_le(
in, crypt64_atoi_map());
237 return generic_encode_le(bytes, crypt64_itoa_map,
false);
241 std::size_t pos = crypt64_itoa_map.find(encoded_char);
242 return pos == std::string::npos ? -1 : pos;
246 return itoa(value, crypt64_itoa_map);
unsigned in
If equal to search_counter, the node is off the list.
std::string encode(utils::byte_string_view bytes)
std::vector< uint8_t > decode(std::string_view in)
std::string encode(utils::byte_string_view bytes)
std::vector< uint8_t > decode(std::string_view in)
std::basic_string_view< uint8_t > byte_string_view