首页 > 编程语言 >C++使用OpenSSL实现Base64编码、解码实例----亲测OK

C++使用OpenSSL实现Base64编码、解码实例----亲测OK

时间:2023-11-30 13:04:02浏览次数:53  
标签:BIO base64 OK Base64 OpenSSL len str xxxx data

摘自:https://www.dandelioncloud.cn/article/details/1498198300963708930

 

// Base64Util.h
#ifndef __BASE64_UTIL_H__
#define __BASE64_UTIL_H__



#ifdef __cplusplus             //告诉编译器,这部分代码按C语言的格式进行编译,而不是C++的
extern "C"{
#endif


string UTIL_base64_encode(const unsigned char *data, unsigned int data_len);
int UTIL_base64_decode(string base64_str, unsigned char **output, unsigned int *out_len);
string hex_2_string(unsigned char *data, unsigned int data_len);


#ifdef __cplusplus             //告诉编译器,这部分代码按C语言的格式进行编译,而不是C++的
}
#endif

#endif /* __BASE64_UTIL_H__ */
//Base64Util.cpp
#include <string>
using namespace std;

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/bio.h>
#include <openssl/evp.h>
//#include "xxxx_platform_common.h"
//#include "liblicense_log.h"
#include "Base64Util.h"

#define DEBUG_BASE64UTIL (1)

#define print_ln(log_level, fmt, ...) do {printf("(%s|%d)" fmt "\r\n", __func__, __LINE__, ##__VA_ARGS__); fflush(stdout);} while(0)
#define xxxx_free(a) do {if(a) {free((void *)a); (a) = NULL;}} while(0)

/*****************************************************************

    Base64编码

    参数 : data, 输入参数, 输入数据
           data_len, 输入参数, 输入数据长度

     return : 长度>0, 成功, 返回 base64 字符串
              长度=0, 失败

*****************************************************************/
string UTIL_base64_encode(const unsigned char *data, unsigned int data_len)
{
    BIO *bio = NULL;
    BIO *b64 = NULL;
    char *buffer = NULL;
    int buf_len = 0;
    string base64_str = "";

    if (NULL == data || 0 >= data_len) {
        xxxx_print_ln(xxxx_ERROR, "wrong parameter.");
        return "";
    }

    // 创建Base64编码的BIO
    b64 = BIO_new(BIO_f_base64());
    BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); // 去掉所有换行符

    bio = BIO_new(BIO_s_mem());
    bio = BIO_push(b64, bio);


    // 写入数据并刷新BIO
    BIO_write(bio, data, (int)data_len);
    (void)BIO_flush(bio);

    // 读取Base64编码后的数据
    buf_len = BIO_get_mem_data(bio, &buffer);
    if (0 >= buf_len) {
        base64_str = "";
        goto __clean;
    }

    buffer[buf_len] = '\0';

    base64_str = (NULL == buffer) ? "" : buffer;

__clean:
    BIO_free_all(bio); // 内部已经 释放buffer

    return base64_str;
}

/*****************************************************************

    Base64解码

    参数 : base64_str, 输入参数, base64 字符串
           output, 输出参数, 输出数据(请调用者自行free)
           out_len, 输出参数, 输出数据长度

     return :  0, 成功
              -1, 失败

*****************************************************************/
int UTIL_base64_decode(string base64_str, unsigned char **output, unsigned int *out_len)
{
    BIO *bio = NULL;
    BIO *b64 = NULL;
    char *buffer = NULL;
    int buf_len = 0;
    int decoded_len = 0;
    int ret = 0;

    if (NULL == output || NULL == out_len) {
        xxxx_print_ln(xxxx_ERROR, "wrong parameter.");
        return -1;
    }

    // 创建Base64解码的BIO
    b64 = BIO_new(BIO_f_base64());
    BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); // 没有换行符

    bio = BIO_new_mem_buf(base64_str.c_str(), base64_str.length());
    bio = BIO_push(b64, bio);


    // 读取Base64解码后的数据
    buf_len = base64_str.length() * 3 / 4;
    buffer = (char *)calloc(1, buf_len + 1);
    if (NULL == buffer) {
        ret = -1;
        xxxx_print_ln(xxxx_ERROR, "malloc Failed(size=%u).", buf_len + 1);
        goto __Failed;
    }

    decoded_len = BIO_read(b64, buffer, base64_str.length());
    if (0 >= decoded_len) {
        ret = -1;
        goto __Failed;
    }

    buffer[decoded_len] = '\0';
    *output = (unsigned char *)buffer;
    *out_len = decoded_len;

    ret = 0;

#if DEBUG_BASE64UTIL
    xxxx_print_ln(xxxx_DEBUG, "decoded_len=%d, buf_len=%d, buffer=%s", decoded_len, buf_len, buffer);
#endif

//__Success:
    BIO_free_all(bio);

    return ret;

__Failed:
    BIO_free_all(bio);
    xxxx_free(buffer);

    return -1;
}

string hex_2_string(unsigned char *data, unsigned int data_len)
{
    string str = "";
    size_t malloc_len = 2 * data_len + 4;
    char *tmp_str = NULL;

    if (NULL == data || 0 >= data_len) {
        xxxx_print_ln(xxxx_ERROR, "wrong parameter.");
        return "";
    }

    tmp_str = (char *)calloc(1, malloc_len);
    if (NULL == tmp_str) {
        xxxx_print_ln(xxxx_ERROR, "malloc Failed(size=%lu).", malloc_len);
        return "";
    }

    for (unsigned int index = 0; index < data_len; index++) {
        snprintf(tmp_str + strlen(tmp_str), malloc_len - strlen(tmp_str) - 1, "%02x", data[index]);
    }


    str = tmp_str;

    xxxx_free(tmp_str);

    return str;
}

#if DEBUG_BASE64UTIL
// 主函数测试Base64编码和解码函数
int main() {
    const char *str = "Hello, World!中华人民";
    string base64_str = "";
    unsigned char *output = NULL;
    unsigned int out_len = 0;
    int ret = 0;

    base64_str = UTIL_base64_encode((const unsigned char *)str, strlen(str));
    ret = UTIL_base64_decode(base64_str, &output, &out_len);

    xxxx_print_ln(xxxx_DEBUG, "base64=%s", base64_str.c_str());
    xxxx_print_ln(xxxx_DEBUG, "ret=%d, out_len=%d, str=%s", ret, out_len, output);

    xxxx_free(output);

    return 0;
}
#endif
g++ Base64Util.cpp -lcrypto

 



标签:BIO,base64,OK,Base64,OpenSSL,len,str,xxxx,data
From: https://blog.51cto.com/u_3078781/8628208

相关文章

  • Nginx loki监控日志的学习
    Nginxloki监控日志的学习背景学习https://mp.weixin.qq.com/s/Qt1r7vzWvCcJpNDilWHuxQ增加了一些自己的理解第一部分nginx日志的完善在logformat的后面增加一个:log_formatjson_analyticsescape=json'{''"msec":"$msec",'#request......
  • npm ERR! Unexpected token ‘.‘ 报错解决办法
    报错截图如下: 解决办法:1、通过nvmuninstall[version]命令将已经安装的node版本依次删除。[version]代表node版本号。 2、找到nvm安装位置,卸载nvm,安装最新版本nvm。我目前安装nvm1.1.12双击nvm目录中的unins000.exe进行卸载。弹窗后点击确定卸载。......
  • nginx依赖包:pcre、zlib、OpenSSL、gd-devel
    学习自:《nginx经典教程》13页1、问题来源在安装nginx时,有一步需要安装依赖包:sudoyuminstallgcc-c++pcrepcre-develzlibzlib-developensslopenssl-devel这一段是啥意思,这些包有什么用?2、依赖包gcc-c++configure脚本中使用的C编译器为cc。该依赖包为C编译器......
  • Tita 升级|「数据驾驶舱」OKR 评分统计表上线
    1. 人员得分表“推荐你关注一下TitaOKR“统计数据:员工每个周期下 OKR 的总分2. OKR评分表统计数据:目标或关键成果的评分详情3. 评分明细表统计数据:每个员工进行的评分详情 ......
  • C语言RsaUtil,C语言Rsa验证签名,验签----自测OK
    摘自:https://www.dandelioncloud.cn/article/details/1498198300963708930 //RsaUtil.c#include<string>usingnamespacestd;#include<stdio.h>#include<stdlib.h>#include<string.h>#include<openssl/rsa.h>#include<openss......
  • Base64编码、解码 C语言例子(使用OpenSSL库)
    #include<stdio.h>#include<string.h>#include<unistd.h>#include<openssl/pem.h>#include<openssl/bio.h>#include<openssl/evp.h>intbase64_encode(char*in_str,intin_len,char*out_str){BIO*b64,*bio;......
  • identityserver4 刷新token接口返回空
    如题,查看日志发现错误信息:Nosigningcredentialforalgorithms(rs256)registered而客户端的配置里的“身份令牌算法”没有rs256于是加上就ok了。 ......
  • vue+iframe 添加请求头,自适应宽度和高度,iframe将token放在请求头不是src的url中
    1<template>2<divclass="iframe">3<iframe4v-if="isRequestHeader"5id="myIframe"6name="myIframe"7src=""8frameborder="0&qu......
  • Docker + supervisor在同一容器中部署zookeeper和kafka
    使用supervisor进程管理工具,在同一个容器中部署zookeeper和kafka目录Dockerfilejdk1.8.0_181.tar.gzkafka_2.12-1.1.0.tgzconf.ddocker-compose.ymlkafka_conf.dconf.d中为supervisor配置文件kafka_conf.d中为kafka配置文件,解压kafka_2.12-1.1.0.tgz中的配置文件,拷贝......
  • SystemSettingsBroker.exe这个奇怪的进程
    系统版本:22621.2715做完PBRReset之后,进入系统,CheckSystemSettingsBroker.exe并没有存在,点击网络图标(TaskBar)后,SystemSettingsBroker.exe进程被拉起了。然后重启系统。 重启系统之后,放置一段时间,系统进入熄屏状态,通过键盘唤醒系统,进入S0,这时发现SystemSettingsBroker.exe又......