IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    使用 boost 执行 base64 解码

    microcai (microcaicai@gmail.com)发表于 2013-03-28 00:00:00
    love 0

    base64 编码最初是为了电子邮件开发的。因为电子邮件是个文本协议,不能传输二进制数据,甚至中文也无法进行传输。只能传输ascii编码的文本。这样一来就诞生了多种将二进制数据编码到ascii里的编码方案,base64是其中之一。

    base64是一种非常简单的编码,只要进行一次迭代即可完成解码。

    什么?一次迭代???

    这就让我们有机会借助 Boost 提供的迭代器非常简洁的写出base64解码器。

    Boost 提供了一个叫 boost::archive::iterators::binaryfrombase64 的迭代器。但是直接使用它并不能完成 base64解码。

    还应该外面再套一层 archive::iterators::transform_width 以 6bit 为单位转换到 8bit。

    typedef archive::iterators::transform_width< 
            archive::iterators::binary_from_base64, 8, 6, char>
                base64decodeIterator;
    

    那么这个就应该是用于解码的 base64decodeIterator

    但是,稍等。如果用来解码电子邮件里的东西,会经常出异常,说有不能允许的字符出现在了base64输入里。

    为什么呢? 因为电子邮件以 78个字符断行了。也就是出现了base64里不允许的 CRLF。

    那么,怎么办? 解码前先替换删除 CRLF ?

    非也非也,这么做是愚蠢的哦,因为我们要的就是一次迭代的效果。 所以,archive::iterators::binaryfrombase64 使用的是 const char * 这个迭代器,对吧,我们改一下,使用 boost::filter_iterator 这个迭代器。过滤掉非base64编码字符。

    boost::filter_iterator 需要使用一个模板参数,参数是一个过滤用的仿函数。

    于是我们写一个

    struct is_base64_char {
    bool operator()(char x) { return boost::is_any_of("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/=")(x);}
    };
    

    然后使用 boost::filteriteratorbase64char, const char*> 作为 archive::iterators::binaryfrom_base64 的迭代器,就形如

    typedef archive::iterators::transform_width< 
                archive::iterators::binary_from_base64 >, 8, 6, char>
                    base64decodeIterator;
    

    然后只要使用 base64decodeIterator(base64string) ,然后执行 ++ 不停的迭代,直到遇到 nul 字符即可完成 base64 字符串解码。为了简化这个迭代过程,可以使用

    std::string result(base64Iterator(str.begin()) , base64Iterator(str.end()));

    这样的形式,则 result 的构造函数内部即会执行迭代,将遍历结果存储于 result 字符串内。

    做一个总结,就编写了如下的函数:



沪ICP备19023445号-2号
友情链接