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

标签 c++ boost base64

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/

相关文章:

c++ - 了解使用 hana::compose 和 shared_ptr 时的内存管理问题

c++ - boost::regex vs std::regex - 找不到 empty() 方法?

css - 在 mozilla 上使用图像源到 base64 时,使用 css 的背景图像不起作用

java - 修改响应体改造2.2拦截器

c++ - 使用 asio boost 线程池 : Threads randomly don't execute

java - 如何从请求 servlet 生成图像

c++ - 'unrelated types' 之间的 static_cast

c++ - C++ 标准是否支持非常量数据成员作为数组边界?

c++ - 如何使用 VS2013(64 位)编译 Boost

c++ - Boost错误代码人类可读的描述