base64编码的两个问题

Posted

技术标签:

【中文标题】base64编码的两个问题【英文标题】:Two questions with base64 encoding 【发布时间】:2015-09-16 12:46:24 【问题描述】:

我对如何将 const char * 转换为 base64 感到困惑,有 2 个问题: 问题 #1 如何定义与输出 base64 的长度完全匹配的输出字符串的长度?我找到了来自苹果开源的代码,下面的代码 http://www.opensource.apple.com/source/QuickTimeStreamingServer/QuickTimeStreamingServer-452/CommonUtilitiesLib/base64.c 或者我可以直接在VC++中使用“atlenc.h”。如果我定义的coded_dst长度小于实际,程序可能会崩溃

int Base64encode(char *coded_dst, const char *plain_src, int len_plain_src)


    const char basis_64[] ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    int i;
    char *p;

    p = coded_dst;
    for (i = 0; i < len_plain_src - 2; i += 3) 
    *p++ = basis_64[(plain_src[i] >> 2) & 0x3F];
    *p++ = basis_64[((plain_src[i] & 0x3) << 4) |
                ((int) (plain_src[i + 1] & 0xF0) >> 4)];
     *p++ = basis_64[((plain_src[i + 1] & 0xF) << 2) |
                ((int) (plain_src[i + 2] & 0xC0) >> 6)];
     *p++ = basis_64[plain_src[i + 2] & 0x3F];
     
     if (i < len_plain_src) 
      *p++ = basis_64[(plain_src[i] >> 2) & 0x3F];
      if (i == (len_plain_src - 1)) 
       *p++ = basis_64[((plain_src[i] & 0x3) << 4)];
       *p++ = '=';
    
   else 
       *p++ = basis_64[((plain_src[i] & 0x3) << 4) |
                    ((int) (plain_src[i + 1] & 0xF0) >> 4)];
       *p++ = basis_64[((plain_src[i + 1] & 0xF) << 2)];
    
    *p++ = '=';
    

     *p++ = '\0';
   return p - coded_dst;
  

问题 #2 众所周知,C++ 中的字节类型是 unsigned char,如何将 char * 转换为 unsigned char *? 谢谢 问候 肯

【问题讨论】:

【参考方案1】:

基于签名的函数设计告诉我,由调用者提供足够的输出缓冲区。在您的示例中这将是不安全的,因为调用者没有通知函数该缓冲区有多大。您的函数没有机会将 coded_dst 的输出限制为提供的缓冲区,因此您至少应该为此添加一个参数。

因此,您需要在循环时检查以确保指向 coded_dst 的指针 p 保持在该限制内,如果空间不足,则向调用者返回错误。

也就是说,请注意每处理 3 个源项目会出现多少 p 增量。比率是 3/4……每 3 个进入该循环,就有 4 个出来。因此,要开始计算所需长度,请从

 ( len_plain_src / 3 ) * 4;

现在,考虑r = len_plain_src % 3; 如果 r 为零,您的算法会增加 2 个字节。如果 r 有余数,您的算法会再增加 3 个字节。

之后,您附加一个零终止符。

仔细看,我没有清楚地分析过这一点,但是对于(i&lt;len_plain_src) 的情况,您可能在尾部附加的结束“=”中有错误 - 您可能添加了两个而不是一个。

现在,要处理 unsigned char,您可以更改 p 的声明和初始分配,

unsigned char * p = (unsigned char *) coded_dst;

此时如果您声明 base_64 为 unsigned char 会更方便

【讨论】:

以上是关于base64编码的两个问题的主要内容,如果未能解决你的问题,请参考以下文章

Mime / Base 64 编码

Golang---BASE64编码原理

在 Java 中如何进行 BASE64 编码和解码

base64编码

什么是base62编码,和base64有什么区别

如何在 React 中对输入进行 base64 编码?