简介
BIO 包含了多种接口,用于控制在BIO_METHOD中的不同实现函数,包含六种filter型和8种source/sink型。
应用场景(Base64编码过程用到的相关内容)
- BIO_NEW创建一个BIO对象
- 数据源:source/sink类型的BIO是数据源BIO_NEW(BIO_s_mem())
- 过滤:filter BIO就是把数据从一个BIO转换到另外一个BIO或应用接口
- BIO_new(BIO_f_base64())
- BIO链:一个BIO链通常包括一个source BIO和一个或多个filter BIO
- BIO _push(b64_bio,mem_bio)
- 写编码,读编码BIO_write;BIO_read_ex (读写都是通过BIO链中BIO_push(b64_bio,mem_bio)的两个参数来实现)
头文件
bio.h:主定义的头文件,包括了很多通用的宏的定义。
bio_lib.c主要的BIO操作定义文件,是比较上层的函数了。
bss_*系列:是soruce/sink型BIO具体的操作实现文件
bf_*系列:是filter型BIO具体的操作实现文件
bio_err.c:是错误信息处理文件
bio_cb.c:是callback函数的相关文件
b_print.c: 是信息输出的处理函数文件
b_socket.c: 是Socket连接的一些相关信息处理文件
b_dump.c: 是对内存内容的存储操作处理
Base64编码
int Base64Encode(const unsigned char* in, int len, char* out_base64)
{
if (!in || len <= 0 || !out_base64)//做校验,检验参数是否合法
return 0;
//内存源source , 从内存中读数据
auto mem_bio = BIO_new(BIO_s_mem());//生成了一个内存的Bio,通过内存源来获取数据,结果要写在内存之中,做一下判断
if (!mem_bio)return 0;
//base64 filter 过滤器 ,从过滤器内写数据
auto b64_bio = BIO_new(BIO_f_base64());
if (!b64_bio)
{
BIO_free(mem_bio);
return 0;
}
//形成BIO链表
//b64-mem
BIO_push(b64_bio, mem_bio);
//写入到base64 filter 进行编码,结果会传递到链表的下一个节点
//到mem中读取结果(从链表头部代表了整个链表,即从链表头部获取数据)
int re = BIO_write(b64_bio, in, len);
if (re <= 0)
{
//情况整个链表节点
BIO_free_all(b64_bio);
return 0;
}
//刷新缓存,写入链表的mem
BIO_flush(b64_bio);
BIO_set_flags(b64_bio, BIO_FLAGS_BASE64_NO_NL);//超过64字节不添加换行,编码的数据在一行中
//默认结尾有换行符\n,超过64字节会再添加换行符
int outsize = 0;
//从链表源内存读取
BUF_MEM* p_data = 0;
BIO_get_mem_ptr(b64_bio, &p_data);
if (p_data)
{
memcpy(out_base64, p_data->data,p_data->length);
outsize = p_data->length;
}
BIO_free_all(b64_bio);
return outsize;
}
Base64解码
int Base64Decode(const char* in, int len, unsigned char* out_data)
{
if (!in || len <= 0 || !out_data)
return 0;
//内存源(密文)
auto mem_bio = BIO_new_mem_buf(in, len);
if (!mem_bio)return 0;
//base64 过滤器
auto b64_bio = BIO_new(BIO_f_base64());
if (!b64_bio)
{
BIO_free(mem_bio);
return 0;
}
//形成BIO链
BIO_push(b64_bio, mem_bio);
//默认换行符作为结束,否则会解码失败,因为除了结尾的换行符还有其他间隔换行符,设置后编码中有\n会失败
BIO_set_flags(b64_bio, BIO_FLAGS_BASE64_NO_NL);
//读取 解码 4字节转3字节
size_t size = 0;
BIO_read_ex(b64_bio,out_data,len, & size);
BIO_free_all(b64_bio);
return size;
}