使用boost进行Base64编码时抛出异常

12

我试图使用Boost Base64编码器,找到了一个例子,但是出现了异常

typedef 
transform_width< binary_from_base64<std::string::const_iterator>, 8, 6 > it_binary_t

an I used

std::string b64E(it_binary_t(Encrip.begin()), it_binary_t(Encrip.end()));

我明白了

在 agentid_coder.exe 中,发生未处理的 Microsoft C++ 异常:boost::archive::iterators::dataflow_exception,地址为 0x0046ed94。

我发现了这个解决方法,但是得到了相同的结果。

 string dec( 
        it_binary_t(Encrip.begin()), 
        it_binary_t(Encrip.begin() + Encrip.length() - 1) 
        ); 

我正在使用 MSVS2008 和 Boost 1.38。


使用Boost C++库的Base64编码函数:http://stackoverflow.com/questions/34680998/attempt-to-decode-a-value-not-in-base64-char-set - ap6491
1个回答

37

很不幸,结合两个 iterator_adaptors binary_from_base64transform_width 并不能完全成为一个base64编码/解码器。Base64将24位(3字节)的数据编码成4个字符,每个字符编码6位。如果输入数据的长度不是3字节的整数倍,则需要用一个或两个零字节进行填充。为了指示添加了多少填充字节,会在编码后的字符串末尾追加一个或两个=字符。

transform_width 负责将8位二进制转换为6位整数,但它不会自动应用这种填充。用户必须手动完成填充操作。以下是一个简单的示例:

#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 <iostream>
#include <string>

using namespace boost::archive::iterators;
using namespace std;

int main(int argc, char **argv) {
  typedef transform_width< binary_from_base64<remove_whitespace<string::const_iterator> >, 8, 6 > it_binary_t;
  typedef insert_linebreaks<base64_from_binary<transform_width<string::const_iterator,6,8> >, 72 > it_base64_t;
  string s;
  getline(cin, s, '\n');
  cout << "Your string is: '"<<s<<"'"<<endl;

  // Encode
  unsigned int writePaddChars = (3-s.length()%3)%3;
  string base64(it_base64_t(s.begin()),it_base64_t(s.end()));
  base64.append(writePaddChars,'=');

  cout << "Base64 representation: " << base64 << endl;

  // Decode
  unsigned int paddChars = count(base64.begin(), base64.end(), '=');
  std::replace(base64.begin(),base64.end(),'=','A'); // replace '=' by base64 encoding of '\0'
  string result(it_binary_t(base64.begin()), it_binary_t(base64.end())); // decode
  result.erase(result.end()-paddChars,result.end());  // erase padding '\0' characters
  cout << "Decoded: " << result << endl;
  return 0;
}
请注意,我添加了insert_linebreaksremove_whitespace迭代器,以使base64输出格式良好,并且可以解码带有换行符的base64输入。这些是可选的。
使用需要不同填充的不同输入字符串运行:
$ ./base64example
Hello World!
Your string is: 'Hello World!'
Base64 representation: SGVsbG8gV29ybGQh
Decoded: Hello World!
$ ./base64example
Hello World!!
Your string is: 'Hello World!!'
Base64 representation: SGVsbG8gV29ybGQhIQ==
Decoded: Hello World!!
$ ./base64example
Hello World!!!
Your string is: 'Hello World!!!'
Base64 representation: SGVsbG8gV29ybGQhISE=
Decoded: Hello World!!!

你可以使用这个在线编码/解码器来检查base64字符串。


2
做得好,已经添加了完整的编码/解码实现!缺少填充也让我感到困扰。 - DanDan
你能解释一下为什么在(3-s.length()%3)%3中需要第二个%3吗? - NoSenseEtAl
我们需要一个{0,1,2}的结果。如果没有第二个%3,我们会得到一个{1,2,3}的结果。最后一个%3将结果3映射为0,并保持1和2不变。另一种可能性是类似于s.length()%3?3-s.length()%3:0的东西。 - PiQuer
哦。:) 顺便问一下,当我在输入字符串末尾有空格时,这会导致崩溃(深入boost)...这是预期的吗? - NoSenseEtAl
1
没有逗号,只是输入字符串末尾有空格...顺便说一句,它崩溃是因为VS2010调试断言,并且我使用的是boost 1-44,所以不幸的是我看不到更多信息,因为像我说的那样,它并没有完全崩溃,只是某些调试断言失败了,而且这是在boost代码中,对于普通人来说是无法解码的。 :D - NoSenseEtAl
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接