127 const auto at = [&str](
auto index) {
return uch(str[index]); };
129 const auto alphabet_char = [](
auto ch) {
130 return static_cast<
char>(
131 base64_alphabet<
unsigned char >()[
132 static_cast<
unsigned char>(ch) ]);
135 constexpr std::size_t group_size = 3u;
136 const auto remaining = str.size() % group_size;
138 result.reserve( (str.size()/group_size + (remaining ? 1:0)) * 4 );
141 for(; i < str.size() - remaining; i += group_size )
143 uint_type_t bs = (at(i) << 16) | (at(i+1) << 8) | at(i+2);
145 result.push_back( alphabet_char( sixbits_char<18>(bs) ) );
146 result.push_back( alphabet_char( sixbits_char<12>(bs) ) );
147 result.push_back( alphabet_char( sixbits_char<6>(bs) ) );
148 result.push_back( alphabet_char( sixbits_char<0>(bs) ) );
154 if( 1u == remaining )
157 result.push_back( alphabet_char( sixbits_char<18>(bs) ) );
158 result.push_back( alphabet_char( sixbits_char<12>(bs) ) );
160 result.push_back(
'=');
166 result.push_back( alphabet_char( sixbits_char<18>(bs) ) );
167 result.push_back( alphabet_char( sixbits_char<12>(bs) ) );
168 result.push_back( alphabet_char( sixbits_char<6>(bs) ) );
171 result.push_back(
'=');
186 if( !is_valid_base64_string( str ) )
189 constexpr std::size_t group_size = 4;
192 result.reserve( (str.size() / group_size) * 3 );
194 const unsigned char *
const decode_table = base64_decode_lut<
unsigned char >();
196 const auto at = [&str](
auto index) {
197 return static_cast<
unsigned char>(str[index]);
200 for( size_t i = 0 ; i < str.size(); i += group_size)
204 int paddings_found = 0u;
206 bs |= decode_table[ at(i) ];
209 bs |= decode_table[ at(i+1) ];
212 if(
'=' == str[i+2] )
218 bs |= decode_table[ at(i+2) ];
222 if(
'=' == str[i+3] )
228 bs |= decode_table[ at(i+3) ];
233 result.push_back( n_bits_from<
char, 16 >(bs) );
234 if( paddings_found < 2 )
236 result.push_back( n_bits_from<
char, 8 >(bs) );
238 if( paddings_found < 1 )
240 result.push_back( n_bits_from<
char, 0 >(bs) );