一、引言
Base64(基底64)是一种基于64个可打印字符来表示二进制数据的表示方法。由于log2 64=6,所以每6个比特为一个单元,对应某个可打印字符。3个字节相当于24个比特,对应于4个Base64单元,即3个字节可由4个可打印字符来表示。在Base64中的可打印字符包括字母A-Z、a-z、数字0-9,这样共有62个字符,此外两个可打印符号在不同的系统中而不同。一些如uuencode的其他编码方法,和之后BinHex的版本使用不同的64字符集来代表6个二进制数字,但是不被称为Base64。
Base64常用于在通常处理文本数据的场合,表示、传输、存储一些二进制数据,包括MIME的电子邮件及XML的一些复杂数据。
Base64编码具有以下特点:1.编码后的数据长度总是比原始数据长约 1/3;2.编码后的数据可以包含 A-Z、a-z、0-9 和两个额外字符的任意组合;3.Base64 编码是一种可逆的编码方式,可以通过解码还原原始数据。
FFmpeg源码中,通过av_base64_decode函数对Base64编码的字符串进行解码。
二、av_base64_decode函数的声明
av_base64_decode函数声明在FFmpeg源码(本文演示用的FFmpeg源码版本为7.0.1)的头文件libavutil/base64.h中:
/**
* Decode a base64-encoded string.
*
* @param out buffer for decoded data
* @param in null-terminated input string
* @param out_size size in bytes of the out buffer, must be at
* least 3/4 of the length of in, that is AV_BASE64_DECODE_SIZE(strlen(in))
* @return number of bytes written, or a negative value in case of
* invalid input
*/
int av_base64_decode(uint8_t *out, const char *in, int out_size);
该函数的作用是:对Base64编码的字符串进行解码。
形参out:输出型参数,存放以Base64解码后的数据的缓冲区。
形参in:输入型参数,存放以Base64编码后的数据的缓冲区。
形参out_size:输入型参数,形参out指向的缓冲区的大小,单位为字节。
返回值:解码成功,返回写入的字节数,即解码后数据占用空间的大小;解码失败,返回一个负数。
三、av_base64_decode函数的定义
av_base64_decode函数定义在源文件libavutil/base64.c中:
int av_base64_decode(uint8_t *out, const char *in_str, int out_size)
{
uint8_t *dst = out;
uint8_t *end;
// no sign extension
const uint8_t *in = in_str;
unsigned bits = 0xff;
unsigned v;
if (!out)
goto validity_check;
end = out + out_size;
while (end - dst > 3) {
BASE64_DEC_STEP(0);
BASE64_DEC_STEP(1);
BASE64_DEC_STEP(2);
BASE64_DEC_STEP(3);
// Using AV_WB32 directly confuses compiler
v = av_be2ne32(v << 8);
AV_WN32(dst, v);
dst += 3;
in += 4;
}
if (end - dst) {
BASE64_DEC_STEP(0);
BASE64_DEC_STEP(1);
BASE64_DEC_STEP(2);
BASE64_DEC_STEP(3);
*dst++ = v >> 16;
if (end - dst)
*dst++ = v >> 8;
if (end - dst)
*dst++ = v;
in += 4;
}
validity_check:
while (1) {
BASE64_DEC_STEP(0);
in++;
BASE64_DEC_STEP(0);
in++;
BASE64_DEC_STEP(0);
in++;
BASE64_DEC_STEP(0);
in++;
}
out3:
if (end - dst)
*dst++ = v >> 10;
v <<= 2;
out2:
if (end - dst)
*dst++ = v >> 4;
out1:
out0:
return bits & 1 ? AVERROR_INVALIDDATA : out ? dst - out : 0;
}
四、参考
《维基百科——Base64》
Base64 编码/解码 | 菜鸟工具