Base64解码过程必须关注的问题

背景

这两天开发工作中,需要运用 Base64来进行数据的编解码。使用 Cryptopp库的 base64(网络上其他基于Boost 的 BIO)都会出现解码出来的字节数只是其中很少的一部分,具体编码结果如下。

原因

1/ 问题的 Base64串

有兴趣的同学可以试试,如下是出现问题的 Base64字符串:

nh5os9KdYYloLDEAAjknMc1mobYofaepkpO8VmQOLmProkitBJHeH8RN0yloaXZ6fU8DxSA6kKL1h9sAqYjd6y5oEZeUfrII2t9Wz0zZyz96QSbpjwJGXFbLWEjwolwyi+fuYnCzpWPPOspEXieuUnEtx2y7GWquGMrf7Vee/GR/ZJOqUNJzK3g59TcjfzhhEaUsm7M65bHQ+TBDC7xDB25gmeao4K/3

2/ 基于 Golang 解码

解码后有168个字节,属于正常的字符串结果。

158 30 104 179 210 157 97 137 104 44 49 0 2 57 39 49 205 102 161 182 40 125 167 169 146 147 188 86 100 14 46 99 235 162 72 173 4 145 222 31 196 77 211 41 104 105 118 122 125 79 3 197 32 58 144 162 245 135 219 0 169 136 221 235 46 104 17 151 148 126 178 8 218 223 86 207 76 217 203 63 122 65 38 233 143 2 70 92 86 203 88 72 240 162 92 50 139 231 238 98 112 179 165 99 207 58 202 68 94 39 174 82 113 45 199 108 187 25 106 174 24 202 223 237 87 158 252 100 127 100 147 170 80 210 115 43 120 57 245 55 35 127 56 97 17 165 44 155 179 58 229 177 208 249 48 67 11 188 67 7 110 96 153 230 168 224 175 247

3/ 基于C++解码

解码后的字节数有168个,但在返回的字符串中只有11个字节,问题也就出现在返回的字符串中。如下返回字符串结果值:

158 30 104 179 210 157 97 137 104 44 49 0

通过对比发现,由于第11个字节刚好被解码为'0',因此在将字节流转换成字符字符串时,理所当然的在该字节后结尾。

4/ Cryptopp 的 Base64解码

通过C++常用的加解密库 Cryptopp 实现的 Base64解码,

string DeBase64Str(const string &content, bool newLine) {
    Base64Decoder decoder;
    decoder.PutMessageEnd((const byte*)content.data(), content.size(), -1, newLine);
    if (!decoder.AnyRetrievable()) {
        return "";
    }

    auto neededLength = decoder.MaxRetrievable(); 
    char *buffer = new char [neededLength];
    decoder.Get((byte *)buffer, neededLength);
    
    std::ostringstream oss;
    oss << buffer;

    delete[] buffer;
    return oss.str();
}
  1. 获取 neededLength变量,有168个字节,库的解码正常;
  2. 获取 buffer 的大小也有168个字节,获取字节流正常;
  3. 获取 oss 大小只有11个字节,因此判断问题出现在 buffer 转 oss 时;

通过对字节输出打印可以看出,在第11个位置的'0'被转义成结尾符,导致 buffer 输出到 oss的主要原因终于找到。

着手对代码进行改进,将 buffer 中的字符一个个输出到 oss 流中,这样就可以避免 buffer 在输出到 oss 自行转义成结尾符,问题得到的解决。

string DeBase64Str(const string &content, bool newLine) {
    Base64Decoder decoder;
    decoder.PutMessageEnd((const byte*)content.data(), content.size(), -1, newLine);
    if (!decoder.AnyRetrievable()) {
        return "";
    }

    auto neededLength = decoder.MaxRetrievable(); 
    char *buffer = new char [neededLength];
    decoder.Get((byte *)buffer, neededLength);
    
    std::ostringstream oss;
    for (size_t i = 0; i < neededLength; I++) {
        oss << buffer[i];    
    }

    delete[] buffer;
    return oss.str();
}

结论

通过上面的问题我们也发现,网上大部分的 Base64解码过程中对于 buff 输出到 oss 存在着直接输出,而非一个个字节输出。

在查找该问题时,我们也在开始认为是解码库本身出现的 Bug,也试用了Boost 的 BIO 方式或者直接 Base64解码方式,得到的结果都一样,只能获取到11个字节。因此,我们排除了解码库本身的 Bug 问题。

或许,你正也在使用 Base64进行解码,刚好也碰上这样的问题,希望这篇文章对你有帮助,或者你使用的 Base64解码已经很稳定,只是未碰到该类问题,可以试试你使用的解码中是否也存在这种问题。

转载于:https://my.oschina.net/john86/blog/883092

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值