可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I am using the following code snippet to base64 encode and decode a string using Boost C++ library.
//Base64 Encode Implementation using Boost C++ library const std::string base64_padding[] = {"", "=", "=="}; std::string X_Privet_Token_Generator::base64_encode(const std::string & s) { namespace bai = boost::archive::iterators; std::stringstream os; // convert binary values to base64 characters typedef bai::base64_from_binary // retrieve 6 bit integers from a sequence of 8 bit bytes <:transform_width char=""> > base64_enc; // compose all the above operations in to a new iterator std::copy(base64_enc(s.c_str()), base64_enc(s.c_str() + s.size()), std::ostream_iterator(os)); os > base64_dec; unsigned int size = s.size(); // Remove the padding characters, cf. if (size && s[size - 1] == '=') { --size; if (size && s[size - 1] == '=') --size; } if (size == 0) return std::string(); LOGINFO("Hash decoded token : %s", s.c_str()); std::copy(base64_dec(s.data()), base64_dec(s.data() + size), std::ostream_iterator(os)); std::cout
Encoding works well, however, while decoding I get the following error:
terminate called after throwing an instance of boost::archive::iterators::dataflow_exception
what()
: attempt to decode a value not in base64 char set
Is it one of the padded characters that is causing this issue? Am I missing something here?
回答1:
The padding characters '=' are part of the b64 encoded data and should not be removed before decoding. b64 is encoded in blocks of 4 character, I suspect that while decoding it reads a '\0' instead of an expected '=' at the end of the string.
回答2:
Changing the
std::copy(base64_dec(s.data()), base64_dec(s.data() + size), std::ostream_iterator(os))
to
return std::string( base64_dec(s.c_str()), base64_dec(s.c_str() + size))
resolved the issue.
回答3:
A more efficient solution for base64 encoding and decoding is as follows:
#include #include #include #include #include #include #include #include std::string X_Privet_Token_Generator::base64_encode(std::string s) { namespace bai = boost::archive::iterators; std::stringstream os; // convert binary values to base64 characters typedef bai::base64_from_binary // retrieve 6 bit integers from a sequence of 8 bit bytes <:transform_width> > base64_enc; // compose all the above operations in to a new iterator std::copy(base64_enc(s.c_str()), base64_enc(s.c_str() + s.size()), std::ostream_iterator(os)); os , 8, 6> base64_dec; unsigned int size = s.size(); // Remove the padding characters. if(size && s[size - 1] == '=') { --size; if(size && s[size - 1] == '=') --size; } if(size == 0) return std::string(); unsigned int paddChars = count(s.begin(), s.end(), '='); std::replace(s.begin(),s.end(), '=', 'A'); std::string decoded_token(base64_dec(s.c_str()), base64_dec(s.c_str() + size)); decoded_token.erase(decoded_token.end()-paddChars,decoded_token.end()); return decoded_token; }