C++ C++;11 Boost,如何将base64解码回整数表示

C++ C++;11 Boost,如何将base64解码回整数表示,c++,boost,base64,C++,Boost,Base64,,我能够编写一些代码,将整数向量转换为base64编码版本。通过与单独的Java实现进行比较,我可以确认它是正确的输出 #include <iostream> #include <iomanip> #include <cstdlib> #include <fstream> #include <iostream> #include <cstdint> #include <typeinfo> #include &

,我能够编写一些代码,将整数向量转换为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";
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
///....
使用名称空间std;
名称空间po=boost::program\u选项;
名称空间fs=boost::filesystem;
名称空间bi=boost::archive::迭代器;
std::stringstream操作系统;
类型定义
bi::base64\u from\u binary
> 
base64_文本;
抄袭(
base64_text(di.cbegin()),
base64_文本(di.cend()),
ostream_迭代器(os)
);

当您试图复制到空向量中时,
copy
不负责插入元素,只负责复制。您必须使用
resize()
预先分配目标向量,或者像这样使用
back\u inserter

vector<int32_t> decoded_ints;
  copy(
       base64_dec(base64ints.cbegin()),
       base64_dec(base64ints.cend()),
       std::back_inserter(decoded_ints)
       );


此外,我认为联系Robert Ramey(boost serialization maintainer)是一个好主意,因为您试图复制到空向量中,
copy
不负责插入元素,只负责复制。您必须使用
resize()
预先分配目标向量,或者像这样使用
back\u inserter

vector<int32_t> decoded_ints;
  copy(
       base64_dec(base64ints.cbegin()),
       base64_dec(base64ints.cend()),
       std::back_inserter(decoded_ints)
       );


此外,我认为与Robert Ramey(boost serialization maintainer)联系是一个好主意。

这确实避免了以前发生的segfault,但不会产生正确的输出。即,返回的整数与解码的原始整数不同。这对我来说很容易检查,因为在我的用例中,所有的整数都是按排序顺序排列的。使用
back\u inserter
可能会导致多次重新分配,除非您事先知道需要的大小并调用
vector.reserve()
。这样可以避免以前发生的segfault,但不会产生正确的输出。即,返回的整数与解码的原始整数不同。这对我来说很容易检查,因为在我的用例中,所有的整数都是按顺序排列的。使用
back\u inserter
可能会导致多次重新分配,除非您事先知道需要的大小并调用
vector.reserve()
。始终提供完整的、最小的、工作的(在您的情况下不工作)示例始终提供完整的、最小的、,工作(在您的情况下不工作)示例
#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;
}