openssl研发之base64编解码实例

news2025/1/12 15:51:55

一、base64编码介绍

Base64编码是一种将二进制数据转换成ASCII字符的编码方式。它主要用于在文本协议中传输二进制数据,例如电子邮件的附件、XML文档、JSON数据等。

Base64编码的特点如下:

  1. 字符集: Base64编码使用64个字符来表示二进制数据,通常使用字母(A-Z、a-z)、数字(0-9)和两个特殊字符(+ 和 /)。有时候,根据具体需求,可能会使用不同的字符集,比如URL安全的Base64编码会使用字符集 A-Za-z0-9-_,其中 “-” 和 “_” 替代了 “+” 和 “/”。

  2. 长度增加: Base64编码通常会导致编码后的数据长度略微增加。每三个字节的二进制数据编码成四个Base64字符。

  3. 填充字符: 如果最后一组不足三个字节,Base64编码会使用一个或两个等号 “=” 进行填充。

  4. 可逆性: Base64编码是可逆的,可以通过解码还原回原始的二进制数据。

  5. 广泛应用: Base64编码广泛应用于数据传输,特别是在文本协议中,以及在一些数据存储和表示的场景中。

下面是一个简单的示例,展示如何对字符串 “Hello, World!” 进行Base64编码:

原始字符串:Hello, World!

Base64编码:SGVsbG8sIFdvcmxkIQ==

二、base64编码原理

Base64编码的原理基于将二进制数据转换成一组可打印字符的过程。它是一种用64个字符来表示所有可能的6位二进制数的方法。以下是Base64编码的基本原理:

  1. 将数据划分成固定长度的块: 首先,将要编码的数据按照一定的规则划分成固定长度的块。通常是每三个字节划分为一组,因为每组有3个字节(24位),正好可以表示为4个Base64字符。

  2. 将块中的二进制数据转换为整数: 将每个块中的三个字节的二进制数据转换为一个24位的整数。这个整数的取值范围是0到2^24-1。

  3. 将整数按6位一组划分: 将上一步得到的整数按照6位一组划分成四组。因为2^6等于64,所以每组的取值范围是0到63。

  4. 将每组的值映射到Base64字符集: 将每一组得到的数值映射到Base64字符集。Base64字符集通常包含64个字符,例如字母A-Z、a-z、数字0-9,以及两个额外的字符(通常是"+“和”/")。这样就得到了四个Base64字符。

  5. 处理末尾的填充: 如果原始数据的长度不是3的倍数,那么最后一个块可能不足3个字节。在这种情况下,会使用一个或两个等号 “=” 进行填充,以保证每个块都是4个Base64字符。

举个例子,假设要编码的数据是"ABC",对应的ASCII码为65、66、67,转换成二进制分别是01000001、01000010、01000011。将这三个字节拼接在一起得到24位的二进制数,然后按照上述步骤转换为Base64编码。最后得到的Base64编码为"QUJD"。

这个过程是可逆的,也就是说,可以通过反向的过程将Base64编码解码回原始的二进制数据。在实际应用中,Base64编码常用于在文本协议中传输二进制数据,或者将二进制数据嵌入到文本文件中。

三、base64开发实例

#include <iostream>
#include <cstring>
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <openssl/buffer.h>

std::string base64_encode(const unsigned char* input, int length) {
    BIO* bio = BIO_new(BIO_f_base64());
    BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);

    BIO* bmem = BIO_new(BIO_s_mem());
    bio = BIO_push(bio, bmem);

    BIO_write(bio, input, length);
    BIO_flush(bio);

    BUF_MEM* bptr;
    BIO_get_mem_ptr(bio, &bptr);

    std::string result(bptr->data, bptr->length);

    BIO_free_all(bio);

    return result;
}

std::string base64_decode(const char* input) {
    BIO* bio = BIO_new(BIO_f_base64());
    BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);

    BIO* bmem = BIO_new_mem_buf(input, -1);
    bio = BIO_push(bio, bmem);

    char buffer[1024];
    int length = BIO_read(bio, buffer, sizeof(buffer));

    BIO_free_all(bio);

    return std::string(buffer, length);
}

int main() {
    const char* originalText = "Hello, Base64!";
    int originalLength = std::strlen(originalText);

    // Base64 编码
    std::string encodedText = base64_encode(reinterpret_cast<const unsigned char*>(originalText), originalLength);
    std::cout << "Base64 Encoded: " << encodedText << std::endl;

    // Base64 解码
    std::string decodedText = base64_decode(encodedText.c_str());
    std::cout << "Base64 Decoded: " << decodedText << std::endl;

    return 0;
}

编译

 g++ main.cpp -o main -lssl -lcrypto

运行结果如下:
在这里插入图片描述

四、源码地址

https://gitcode.net/arv002/qt/-/tree/master/Openssl/hash/base64

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1198433.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

UPLAOD-LABS2

less7 任务 拿到一个shell服务器 提示 禁止上传所有可以解析的后缀 发现所有可以解析的后缀都被禁了 查看一下源代码 $is_upload false; $msg null; if (isset($_POST[submit])) {if (file_exists($UPLOAD_ADDR)) {$deny_ext array(".php",".php5&quo…

password game

目录 password game &#xff08;1-2&#xff09; &#xff08;3&#xff09; &#xff08;4&#xff09; &#xff08;5&#xff09; &#xff08;6&#xff09; &#xff08;7&#xff09; &#xff08;8&#xff09; &#xff08;9&#xff09; &#xff08;10&am…

CCF ChinaSoft 2023 论坛巡礼|机器人大模型与具身智能挑战赛

2023年CCF中国软件大会&#xff08;CCF ChinaSoft 2023&#xff09;由CCF主办&#xff0c;CCF系统软件专委会、形式化方法专委会、软件工程专委会以及复旦大学联合承办&#xff0c;将于2023年12月1-3日在上海国际会议中心举行。 本次大会主题是“智能化软件创新推动数字经济与社…

第一百六十九回 如何修改NavigationBar的形状

文章目录 1. 概念介绍2. 使用方法3. 代码与效果3.1 示例代码3.2 运行效果 4. 内容总结 我们在上一章回中介绍了"如何修改按钮的形状"相关的内容&#xff0c;本章回中将介绍NavigationBar组件.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们在本章…

【java进阶】集合的三种遍历(迭代器、增强for、Lambda)

目录 一、先谈集合&#xff1a; 二、单列集合的三种遍历方式 迭代器遍历 增强for遍历 Lambda表达式遍历 一、先谈集合&#xff1a; &#x1f525;那我们平常用for循环依赖下标遍历不行嘛&#xff0c;这就与集合的分类有关了。 集合的体系结构&#xff1a; collection是单…

我的前端笔记JS

js介绍 js是编程语音&#xff0c;之前学的html和css是标记语言 百度搜索mdn官网就可以 语法 输出、对话框、控制台日志、输入对话框 字面量 简单理解就是看到的内容是属于什么类型&#xff0c;例如1232&#xff0c;这个是属于数字字面量

【C++】this指针讲解超详细!!!

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …

如何用 GPTs 构建自己的知识分身?(进阶篇)

&#xff08;注&#xff1a;本文为小报童精选文章&#xff0c;已订阅小报童或加入知识星球「玉树芝兰」用户请勿重复付费&#xff09; 有了这些改进&#xff0c;你可以快速判断 GPT 助手给出的答案是真实还是「幻觉」了。 问题 在《如何用自然语言 5 分钟构建个人知识库应用&am…

【Git】Git使用Gui图形化界面,Git中SSH协议,Idea集成Git

一&#xff0c;Git使用Gui图形化界面 1.1 Gui的简介 Gui &#xff08;Graphical User Interface&#xff09;指的是图形用户界面&#xff0c;也就是指使用图形化方式来协同人和计算机进行交互的一类程序。它与传统的命令行界面相比&#xff0c;更加直观、易用&#xff0c;用户…

MATLAB的编程与应用,匿名函数、嵌套函数、蒙特卡洛法的掌握与使用

目录 1.匿名函数 1.1.匿名函数的定义与分类 1.2.匿名函数在积分和优化中应用 2.嵌套函数 2.1.嵌套函数的定义与分类 2.2.嵌套函数彼此调用关系 2.3.嵌套函数在积分和微分中应用 3.微分和积分 4.蒙特卡洛法 4.1.圆周率的模拟 4.2.计算N重积分&#xff08;均匀分布&am…

Python与ArcGIS系列(一)ArcGIS中使用Python

目录 0 简述1 arcgis中的python窗口2 开始编写代码 0 简述 按照惯例&#xff0c;作为本系列专栏的第一篇&#xff0c;先简单地介绍下本系列文章的内容&#xff1a;通过python语言创建arcgis环境脚本、将脚本以工具箱形式存放在arcgis中、通过脚本自动执行地理处理、数据修复、…

Benchmarking Large Language Models in Retrieval-Augmented Generation-学习翻译

提检索增强生成中大型语言模型的基准测试文献学习 作者将在https://github.com/chen700564/RGB上发布本文的代码和RGB。 y ˇ \check{y} yˇ​ 文章目录 摘要IntroductionRelated workRetrieval-Augmented Generation BenchmarkRAG所需能力数据构建评估指标 ExperimentsSetting…

kubeadm部署k8s及高可用

目录 CNI 网络组件 1、flannel的功能 2、flannel的三种模式 3、flannel的UDP模式工作原理 4、flannel的VXLAN模式工作原理 5、Calico主要组成部分 6、calico的IPIP模式工作原理 7、calico的BGP模式工作原理 8、flannel 和 calico 的区别 Kubeadm部署k8s及高可用 1、…

Vue3 源码解读系列(四)——组件更新

组件更新 组件更新流程&#xff1a; 从头部开始同步 从尾部开始同步 挂载剩余的新节点 删除多余的旧节点 处理未知的子序列 当两个节点类型相同时&#xff0c;执行更新操作当新子节点中没有旧子节点中的某些节点时&#xff0c;执行删除操作当新子节点中多了旧子节点中没有…

小样本目标检测(Few-Shot Object Detection)综述

背景 前言:我的未来研究方向就是这个,所以会更新一系列的文章,就关于FSOD,如果有相同研究方向的同学欢迎沟通交流,我目前研一,希望能在研一发文,目前也有一些想法,但是具体能不能实现还要在做的过程中慢慢评估和实现.写文的主要目的还是记录,避免重复劳动,我想用尽量简洁的语言…

141.环形链表(LeetCode)

想法一 快慢指针&#xff0c;设置slow和fast指针&#xff0c;slow一次走一步&#xff0c;fast一次走两步&#xff0c;如果链表有环&#xff0c;它们最终会相遇&#xff0c;相遇时返回true&#xff1b;如果链表无环&#xff0c;它们最终走到空&#xff0c;跳出循环&#xff0c;…

计算机视觉中目标检测的数据预处理

本文涵盖了在解决计算机视觉中的目标检测问题时&#xff0c;对图像数据执行的预处理步骤。 首先&#xff0c;让我们从计算机视觉中为目标检测选择正确的数据开始。在选择计算机视觉中的目标检测最佳图像时&#xff0c;您需要选择那些在训练强大且准确的模型方面提供最大价值的图…

自动化测试 —— requests和selenium模块!

一、requests基于POST请求 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #1.requests的GET与POST用法的区别&#xff1a; GET请求: (HTTP默认的请求方法就是GET) * 没有请求体 * 数据必须在1K之内&#xff01; * GET请求数据会暴露在浏览器…

YOLOv5算法进阶改进(1)— 改进数据增强方式 + 添加CBAM注意力机制

前言:Hello大家好,我是小哥谈。本节课设计了一种基于改进YOLOv5的目标检测算法。首先在数据增强方面使用Mosaic-9方法来对训练集进行数据增强,使得网络具有更好的泛化能力,从而更好适用于应用场景。而后,为了更进一步提升检测精度,在backbone中嵌入了CBAM注意力机制模块,…

uniapp中在组件中使用被遮挡或层级显示问题

uniapp中在组件中使用或croll-view标签内使用uni-popup在真机环境下会被scroll-view兄弟元素遮挡&#xff0c;在开发环境下和安卓系统中可以正常显示&#xff0c;但在ios中出现了问题 看了许多文章都没有找到问题的原因&#xff0c;最后看到这一个文章http://t.csdnimg.cn/pvQ…