我已经能够使用boost和以下代码将std::vector<char>
编码为Base64:
using namespace boost::archive::iterators;
std::string message(binary.begin(), binary.end());
std::stringstream os;
using base64_text = insert_linebreaks<base64_from_binary<transform_width<const char *, 6, 8>>, 72>;
std::copy(
base64_text(message.c_str()),
base64_text(message.c_str() + message.size()),
ostream_iterator<char>(os)
);
return os.str();
我在Stackoverflow上发现了这个。好吧,现在我想向后退一步,放入Base64格式std::string
,最后得到std::vector<char>
。但我不能适应我的榜样来反过来做事。我在网上找到了一些其他的代码,这对于Hello World示例很有用,但是当有一个实际更大的Base64时,它还包含一些像反斜杠这样的关键字符,整个事情就会崩溃。
这就是我现在正在做的解码:
using namespace std;
using namespace boost::archive::iterators;
typedef
transform_width<
binary_from_base64<string::const_iterator>, 8, 6
> binary_t;
string dec(binary_t(str.begin()), binary_t(str.end()));
return dec;
当我要创建字符串时,它会在返回前的最后一行崩溃。 你知道它有什么问题吗?
答案 0 :(得分:5)
base64
要求输入和输出分别填充为3和4的倍数。
这是使用boost
解码base64的函数:
#include <boost/archive/iterators/base64_from_binary.hpp>
#include <boost/archive/iterators/binary_from_base64.hpp>
#include <boost/archive/iterators/transform_width.hpp>
#include <boost/archive/iterators/insert_linebreaks.hpp>
#include <boost/archive/iterators/remove_whitespace.hpp>
#include <algorithm>
std::string decode(std::string input)
{
using namespace boost::archive::iterators;
typedef transform_width<binary_from_base64<remove_whitespace
<std::string::const_iterator> >, 8, 6> ItBinaryT;
try
{
// If the input isn't a multiple of 4, pad with =
size_t num_pad_chars((4 - input.size() % 4) % 4);
input.append(num_pad_chars, '=');
size_t pad_chars(std::count(input.begin(), input.end(), '='));
std::replace(input.begin(), input.end(), '=', 'A');
std::string output(ItBinaryT(input.begin()), ItBinaryT(input.end()));
output.erase(output.end() - pad_chars, output.end());
return output;
}
catch (std::exception const&)
{
return std::string("");
}
}
它来自here,其中也可以找到使用boost
填充的编码函数。
答案 1 :(得分:1)
以下是1_65_1/boost/archive/iterators/transform_width.hpp
的引用// iterator which takes elements of x bits and returns elements of y bits. // used to change streams of 8 bit characters into streams of 6 bit characters. // and vice-versa for implementing base64 encodeing/decoding. Be very careful // when using and end iterator. end is only reliable detected when the input // stream length is some common multiple of x and y. E.G. Base64 6 bit // character and 8 bit bytes. Lowest common multiple is 24 => 4 6 bit characters // or 3 8 bit characters
所以看起来你必须填充字符串进行编码(例如使用零字符)以避免此类问题,并在解码后截断它们
答案 2 :(得分:1)
我尝试了kenba可接受的解决方案,并遇到了一些我在下面解决的问题。首先,尾随空格将导致任何remove_whitespace迭代器跳过end(),从而导致内存错误。其次,由于您正在计算未过滤字符串的填充,因此任何带有空格的base64编码字符串都会产生错误数量的pad_chars。解决方案是在对字符串进行其他操作之前预先过滤空格。
#include <boost/archive/iterators/base64_from_binary.hpp>
#include <boost/archive/iterators/binary_from_base64.hpp>
#include <boost/archive/iterators/transform_width.hpp>
#include <boost/archive/iterators/insert_linebreaks.hpp>
#include <boost/archive/iterators/remove_whitespace.hpp>
#include <algorithm>
inline void decode_base64( std::string input, std::vector<char>& output )
{
using namespace boost::archive::iterators;
typedef remove_whitespace<std::string::const_iterator> StripIt;
typedef transform_width<binary_from_base64<std::string::const_iterator>, 8, 6> ItBinaryT;
try
{
/// Trailing whitespace makes remove_whitespace barf because the iterator never == end().
while (!input.empty() && std::isspace( input.back() )) { input.pop_back(); }
input.swap( std::string( StripIt( input.begin() ), StripIt( input.end() ) ) );
/// If the input isn't a multiple of 4, pad with =
input.append( (4 - input.size() % 4) % 4, '=' );
size_t pad_chars( std::count( input.end() - 4, input.end(), '=' ) );
std::replace( input.end() - 4, input.end(), '=', 'A' );
output.clear();
output.reserve( input.size() * 1.3334 );
output.assign( ItBinaryT( input.begin() ), ItBinaryT( input.end() ) );
output.erase( output.end() - (pad_chars < 2 ? pad_chars : 2), output.end() );
}
catch (std::exception const&)
{
output.clear();
}
}