Based on this code here ,我能够编写一些代码将整数 vector 转换为 base64 编码版本。通过与单独的 Java 实现进行比较,我可以确认它是正确的输出。
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <cstdint>
#include <typeinfo>
#include <boost/program_options.hpp>
#include <boost/filesystem.hpp>
#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/ostream_iterator.hpp>
#include <boost/archive/iterators/remove_whitespace.hpp>
///....
using namespace std;
namespace po = boost::program_options;
namespace fs = boost::filesystem;
namespace bi = boost::archive::iterators;
std::stringstream os;
typedef
bi::base64_from_binary< // convert binary values to base64 characters
bi::transform_width< // retrieve 6 bit integers from a sequence of 32 bit ints
vector<int32_t>::const_iterator,
6,
32
>
>
base64_text;
copy(
base64_text(di.cbegin()),
base64_text(di.cend()),
ostream_iterator<char>(os)
);
cout << os.str() << "\n";
现在我正在尝试编写代码以将其解码回整数 vector ,但事实证明这要困难得多。我试图将给定的示例转换为我的用例(见下文),但我只是在复制调用中遇到无用的段错误。令人沮丧的是,我发现的一切都是假设字符串输入/输出进行编码/解码。任何帮助表示赞赏。
typedef
bi::transform_width<
bi::binary_from_base64<bi::remove_whitespace<string::const_iterator>>,
32, 6
>
base64_dec;
vector<int32_t> decoded_ints;
copy(
base64_dec(base64ints.cbegin()),
base64_dec(base64ints.cend()),
decoded_ints.begin()
);
最佳答案
您正在尝试复制到空 vector 中,copy
不负责插入元素,只负责复制。您必须使用 resize()
预分配目标 vector 或者只使用 back_inserter
像这样
vector<int32_t> decoded_ints;
copy(
base64_dec(base64ints.cbegin()),
base64_dec(base64ints.cend()),
std::back_inserter(decoded_ints)
);
EDIT001:由于没有给出更好的答案,尽管没有引入最小的工作示例,而且我不知道为什么会出现段错误,我将扩展我的答案。
上面的代码应该可以工作,以及初始化你的 int
vector
声明时 - 类似于 vector<int32_t> decoded_ints(base64_dec(base64ints.cbegin()),base64_dec(base64ints.cend()))
但是,您的整个代码不起作用,没有检查它是否正确编码数据,但它在解码时肯定不会产生正确的结果。看起来像 transform_width
不能用大于 8 位的东西来解决这个问题,或者在编码数据中添加了填充,解码时应该考虑到这一点。在任何情况下,您都可以通过将 int vector 插入字符串(或 int8_t 的 vector )来解决所有这些问题。像这样。
#include <boost/archive/iterators/base64_from_binary.hpp>
#include <boost/archive/iterators/binary_from_base64.hpp>
#include <boost/archive/iterators/transform_width.hpp>
#include <vector>
#include <iostream>
#include <memory.h>
int main()
{
using namespace std;
namespace bi = boost::archive::iterators;
using IntVec = vector<int32_t>;
IntVec di(1024, 0);
int32_t n = 0;
std::generate(di.begin(), di.end(), [&n]() { return n++; });
string input(reinterpret_cast<string::pointer>(di.data()),
reinterpret_cast<string::pointer>(di.data()) + (di.size() * sizeof(IntVec::value_type)));
typedef bi::base64_from_binary<bi::transform_width<string::const_iterator, 6, 8>> base64_text;
typedef bi::transform_width<bi::binary_from_base64<string::const_iterator>, 8, 6> base64_dec;
std::string base64ints(base64_text(input.cbegin()), base64_text(input.cend()));
string decoded(base64_dec(base64ints.begin()), base64_dec(base64ints.end()));
IntVec decoded_ints(reinterpret_cast<IntVec::const_pointer>(decoded.data()),
reinterpret_cast<IntVec::const_pointer>(decoded.data()) +
(decoded.size() / sizeof(IntVec::value_type)));
if (decoded_ints.size() == di.size())
cout << "Size matches" << std::endl;
else
cout << "Size does not match" << std::endl;
if (memcmp(decoded_ints.data(), di.data(), di.size() * sizeof(int32_t)) == 0)
cout << "Data matches" << std::endl;
else
cout << "Data does not match" << std::endl;
}
Live on CoLiRu
此外,我认为联系 Robert Ramey(boost 序列化维护者)是个好主意 Boost Mailing List
关于C++11 Boost,如何将 base64 解码回整数表示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44380979/