【问题标题】:Base64 encode using boost throw exceptionBase64 编码使用 boost throw 异常
【发布时间】:2012-05-18 07:01:11
【问题描述】:

我尝试使用 boost base64 编码器,我找到了一个示例,但我得到了异常

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

我用过的

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

我明白了

agentid_coder.exe 中 0x75b1b9bc 处未处理的异常: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

【问题讨论】:

标签: c++ string boost iterator base64


【解决方案1】:

不幸的是iterator_adaptorsbinary_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!!!

你可以用这个online-encoder/decoder检查base64字符串。

【讨论】:

  • 添加完整的编码/解码实现做得很好!缺少填充也让我感到困惑。
  • 你能解释一下为什么你需要第二个 %3 in (3-s.length()%3)%3
  • 我们需要 {0,1,2} 中的结果。如果没有第二个 %3,我们会在 {1,2,3} 中得到结果。最后一个 %3 将结果 3 映射到 0 并单独留下 1 和 2。另一种可能性是 s.length()%3?3-s.length()%3:0
  • 多哈。 :) 顺便说一句,当我在输入字符串的末尾有空格时,这会崩溃(深入提升)......这是预期的吗?
  • 不,只是输入字符串末尾有空格...顺便说一句,由于 VS2010 调试断言和我在 boost 1-44 上它崩溃了,所以不幸的是我看不到我可以给你更多信息,因为喜欢我说它不会崩溃崩溃,一些调试断言失败并且它是在普通人无法解码的 boost 代码中。 :D
猜你喜欢
  • 2011-10-26
  • 1970-01-01
  • 1970-01-01
  • 2015-07-14
  • 2013-06-03
  • 2018-03-05
  • 2015-01-09
  • 2011-12-23
  • 1970-01-01
相关资源
最近更新 更多