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<len_plain_src)
的情况,您可能在尾部附加的结束“=”中有错误 - 您可能添加了两个而不是一个。
现在,要处理 unsigned char,您可以更改 p 的声明和初始分配,
unsigned char * p = (unsigned char *) coded_dst;
此时如果您声明 base_64 为 unsigned char 会更方便
【讨论】:
以上是关于base64编码的两个问题的主要内容,如果未能解决你的问题,请参考以下文章