利用Base64加密算法将数据加密解密

1. Base64加密算法

Base64准确来说并不像是一种加密算法,而更像是一种编码标准。

我们知道现在最为流行的编码标准就是ASCLL,它用八个二进制位(一个char的大小)表示了127个字符,任何二进制序列都可以用这127个字符表示出来。

而Base64则是用6个二进制位表示了64个字符,也就是说,任何的二进制序列也都可以用这64个字符表示出来,这也是其名称的来源。

我们加密的方法,就是将原来的信息以ACSLL的标准转化为二进制序列(如果不是6的倍数,就用0补齐),然后按照Base64的标准,将其转化为该标准下的字符。

例如:

ASCLL(含换行符):

hello world
hello world
hello world

Base64:

aGVsbG8gd29ybGQKaGVsbG8gd29ybGQKaGVsbG8gd29ybGQA

如此加密之后的信息具有不可读性,广泛运用通信领域。

但是,这样加密过后的信息并不安全,只要你有心,就可以对照Basd64对照表和ASCLL码表解密出原来的内容。

对于Base64算法,我们仅做这么多介绍,感兴趣的小伙伴可以自己去深入了解一下。

2. 加密解密函数函数

2.1 加密函数Into_Base64

函数原型如下方代码所示。

在使用时,要求用户传入目标文件和原文件的文件名,函数就可以将原文件的信息加密存储到目标文件中。

void Into_Base64(const char dest[], const char src[])//加密函数//目标文件,源文件
{
    FILE* srcx = fopen(src, "r");
    if(srcx == NULL)
    {
        perror("source:");
        return;
    }
    FILE* destx = fopen(dest, "w");
    if(destx == NULL)
    {
        perror("destination:");
        return;
    }
    int flag = 1;
    while(flag)
    {
        char secret[5] = {0};//存储加密后数据
        int binary[25] = {0};//6和8的最小公倍数为24
        char ch = 0;
        for(int i = 0; i < 3; i++)
        {
            ch = getc(srcx);
            if(ch == -1)
            {
                flag = 0;
                goto interruption;
            }
            Into_Binary(binary + i * 8, ch, 0);
        }
        interruption:
        for(int i = 0; i < 4; i++)
        {
            Into_Char(secret + i, binary + i * 6, 1);
        }
        fprintf(destx, "%s", secret);
    }
    
    fclose(srcx);
    fclose(destx);
}

在while循环中,我们每次读取24个字节的数据,这是因为6(Base64中一个字符的二进制长度)和8(ASCLL中一个字符的二进制长度)的最小公倍数为24,便于实现两种编码之间的转换。

2.2 解密函数Out_Base64

函数原型如下方代码所示。

在使用时,要求用户传入目标文件和原文件的文件名,函数就可以将原文件的信息解密存储到目标文件中。

void Out_Base64(const char dest[], const char src[])//解密函数//目标文件,源文件
{
    FILE* srcx = fopen(src, "r");
    if(srcx == NULL)
    {
        perror("source:");
        return;
    }
    FILE* destx = fopen(dest, "w");
    if(destx == NULL)
    {
        perror("destination:");
        return;
    }
    int flag = 1;
    while(flag)
    {
        char secret[4] = {0};//存储解密后数据//
        int binary[25] = {0};//6和8的最小公倍数为24
        char ch = 0;
        for(int i = 0; i < 4; i++)
        {
            ch = getc(srcx);
            if(ch == -1)
            {
                flag = 0;
                goto interruption;
            }
            Into_Binary(binary + i * 6, ch, 1);
        }
        interruption:
        for(int i = 0; i < 3; i++)
        {
            Into_Char(secret + i, binary + i * 8, 0);
        }
        fprintf(destx, "%s", secret);
    }
    
    fclose(srcx);
    fclose(destx);
}

该函数与加密函数基本相同,只是在调用Into_Binary函数和Into_Char函数时的传参时有所差别,并且每24个字节解密得到的字符的仅有三个,所以secret数组的容量也相应减少了。

2.3 字符转二进制序列函数Into_Binary

函数原型如下方代码所示。

在使用时,要求用户传入存储二进制序列的数组的起始地址,要转换的字符,以及flag。

其中,flag==1时,将字符按照Base64编码转换为二进制;flag==0时,将字符按照ASCLL编码转换为二进制。

在加密函数中,flag==0;在解密函数中flag==1。

//将src转换为二进制存到dest中
//flag==1将Base64编码转换为二进制,flag==0将ascll转换为二进制
void Into_Binary(int* dest, char src, int flag)
{
    int n = 2;
    int num = 0;
    if(flag)
    {
        num = 5;//六位,最高位下标5
        src = Base64_Int(src);
    }
    else
    {
        num = 7;//八位,最高位下标7
    }
    for(int i = num; i >= 0; i--)
    {
        *(dest + i) = src % n;
        src /= 2;
    }
}

由于计算机是以ASCLL编码标准识别字符的,所以我们直接将其当作整形处理即可。

但是计算机并不懂得Base64的编码标准是怎样的,所以我写了一个函数,将字符按照Base64标准转换为整形。

char Base64_Int(char tem)//字符转Base64编码
{
    if(tem >= 'A'&&tem <= 'Z')
    return tem - 'A';
    else if(tem >= 'a'&&tem <= 'z')
    return tem + 26 - 'a';
    else if(tem >= '0'&&tem <= '9')
    return tem + 52 - '0';
    else if(tem == '+')
    return 62;
    else if(tem == '/')
    return 63;
}

2.4 二进制序列转字符函数

函数原型如下方代码所示。

在使用时,要求用户传入存储要转换的二进制序列的数组的起始地址,存储转换后字符的地址,以及flag。

其中,flag==1时,将二进制序列按Base64编码转换为字符;flag==0时,将二进制序列按ASCLL编码转换为字符。

在加密函数中,flag==1;在解密函数中flag==0。

//将二进制数转换为char类型
//flag==1转换为Base64,flag==0转换为ascll
void Into_Char(char* dest, int* src, int flag)
{
    int tem = 0;
    int n = 1;
    int num = 0;
    if(flag)
    num = 5;
    else
    num = 7;
    for(int i = num; i >= 0; i--)
    {
        tem += *(src + i) * n;
        n *= 2;
    }
    if(flag)
    *dest = Base64_Char(tem);
    else
    *dest = tem;
}

与刚才同理,Base64_Char用于将整形按照Base64标准转换为字符。

char Base64_Char(int tem)//Base64编码转字符
{
    if(tem >= 0&&tem <= 25)
    return tem + 'A';
    else if(tem >= 26&&tem <= 51)
    return tem + 'a' - 26;
    else if(tem >= 52&&tem <= 61)
    return tem + '0' - 52;
    else if(tem == 62)
    return '+';
    else if(tem == 63)
    return '/';
}

3. 测试

写好之后,我们就可以写个main函数来进行一下测试啦!

int main()
{
    Into_Base64("test2.txt", "test1.txt");//把test1.txt加密后存到test2.txt
    Out_Base64("test3.txt", "test2.txt");//把test2.txt解密后存到test3.txt
    return 0;
}

注意要先创建好“test1.txt”文件,以免打开文件时失败。

运行之后得到两个文件

 

也是包成功的啊。 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

chap验证实验

一、添加接口 在每个路由器里添加2SA接口 二、配IP 进入serial接口配置IP R1&#xff1a; R2&#xff1a; ppp mp Mp-group 0/0/0 R3: 查看&#xff1a; 三、aaa认证&#xff0c;chap验证 创建一个新用户&#xff1a; R2进入3/0/0接口&#xff1a; R1进入3/0/0接口&a…

制作一个RISC-V的操作系统六-bootstrap program(risv 引导程序)

文章目录 硬件基本概念qemu-virt地址映射系统引导CSR![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/86461c434e7f4b1b982afba7fad0256c.png)machine模式下的csr对应的csr指令csrrwcsrrs mhartid引导程序做的事情判断当前hart是不是第一个hart初始化栈跳转到c语言的…

【Android开发】【创建Activity,Activity之间的切换/消息传递】【java】

一、第一个Activity 1.1 创建一个空Activity 1.2 创建一个布局 知识点 在XML中引用一个id&#xff1a;id/id_name 在XML中定义一个id&#xff1a;id/id_name 右键错误&#xff0c;点击Show Quick-Fixes&#xff0c;再点击弹出的Suppress:Add........&#xff0c;错误会被自动修…

详细分析PyAutoGUI中的locate函数(附Demo)

目录 前言1. 基本知识2. 源代码分析3. Demo 前言 起因是实战中locate对个别定位会有偏差&#xff0c;导致一直识别错误 相应的基本知识推荐阅读&#xff1a;详细分析Python中的Pyautogui库&#xff08;附Demo&#xff09; 1. 基本知识 pyautogui.locate()函数用于在屏幕上定…

DBO优化朴素贝叶斯分类预测(matlab代码)

DBO-朴素贝叶斯分类预测matlab代码 蜣螂优化算法(Dung Beetle Optimizer, DBO)是一种新型的群智能优化算法&#xff0c;在2022年底提出&#xff0c;主要是受蜣螂的的滚球、跳舞、觅食、偷窃和繁殖行为的启发。 数据为Excel分类数据集数据。 数据集划分为训练集、验证集、测试…

YOLO-v8-seg实例分割使用

最近需要实例分割完成一些任务&#xff0c;一直用的SAM(segment anything&#xff09;速度慢&#xff0c;找一个轻量分割模型。 1. YOLO-v8-seg使用 git clone https://github.com/ultralytics/ultralytics.git cd ultralytics vim run.py from ultralytics import YOLO# L…

鸿蒙一次开发,多端部署(十三)功能开发的一多能力介绍

应用开发至少包含两部分工作&#xff1a; UI页面开发和底层功能开发&#xff08;部分需要联网的应用还会涉及服务端开发&#xff09;。前面章节介绍了如何解决页面适配的问题&#xff0c;本章节主要介绍应用如何解决设备系统能力差异的兼容问题。 系统能力 系统能力&#xff…

RK3568驱动指南|第十三篇 输入子系统-第143章 多对多的匹配关系分析

瑞芯微RK3568芯片是一款定位中高端的通用型SOC&#xff0c;采用22nm制程工艺&#xff0c;搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码&#xff0c;支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU&#xff0c;可用于轻量级人工…

有哪些强大好用的AI表格数据处理工具或者 AI Excel工具?

在繁忙的工作和生活中&#xff0c;处理大量的表格数据往往令人感到头疼。面对一列列数字、一行行文字&#xff0c;我们需要花费大量的时间和精力去整理、核对。然而&#xff0c;随着科技的飞速发展&#xff0c;人工智能&#xff08;AI&#xff09;技术正逐渐改变这一现状。 如…

LLM 面试知识点——模型基础知识

1、主流架构 目前LLM(Large Language Model)主流结构包括三种范式,分别为Encoder-Decoder、Causal Decoder、Prefix Decode。对应的网络整体结构和Attention掩码如下图。 、 各自特点、优缺点如下: 1)Encoder-Decoder 结构特点:输入双向注意力,输出单向注意力。 代表…

Flutter开发进阶之瞧瞧RenderObject

Flutter开发进阶之瞧瞧RenderObject 通过上回我们了解到Flutter执行buildTree的逻辑线&#xff0c;当Tree构建完成后会交给Flutter底层的渲染事件循环去执行将内容渲染到屏幕的操作。 但是渲染的操作到底是如何串起来的呢&#xff1f;这篇文章将会从Element联系到RenderObject…

点餐小程序php毕设项目

主要技术框架&#xff1a; 主要功能模块&#xff1a; 商品管理 订单管理 用户管理 优惠券管理 商品分类管理 评论管理 轮播图管理 截图 获取源码 https://blog.lusz.top/article?article_id-2

【Linux系统编程(进程编程)】创建进程的场景,fork和vfork的使用及区别

文章目录 一、进程关键概念二、创建进程函数fork的使用一、进程创建实战 三、创建进程函数fork的使用补充四、进程创建发生了什么事&#xff1f;五、创建新进程的实际应用场景 & fork总结一、fork创建一个子进程的一般目的&#xff1f;二、fork编程实战 六、vfork也能创建进…

grid布局

文章目录 1. 概念2. 组成2.1. 网格行2.2. 网格列2.3. 网格间距2.4. 网格线2.5. 网格容器2.6. fr 单位 3. 网格跨行跨列3.1. 跨列3.2. 跨行 4. 网格布局案例4.1. 演示效果4.2. 分析思路4.3. 代码实现 1. 概念 网格是一组相交的水平线和垂直线&#xff0c;它定义了网格的列和行。…

【排序算法】实现快速排序值(霍尔法三指针法挖坑法优化随即选key中位数法小区间法非递归版本)

文章目录 &#x1f4dd;快速排序&#x1f320;霍尔法&#x1f309;三指针法&#x1f320;挖坑法✏️优化快速排序 &#x1f320;随机选key&#x1f309;三位数取中 &#x1f320;小区间选择走插入&#xff0c;可以减少90%左右的递归&#x1f309; 快速排序改非递归版本&#x1…

工业相机采图方式、图像格式(BYTE、HObject和Mat)转换

1、概述 机器视觉项目中&#xff0c;如何采集到合适的图像是项目的第一步&#xff0c;也是最重要的一步&#xff0c;直接关系到后面图像处理算法及最终执行的结果。所以采用不同的工业相机成像以及如何转换成图像处理库所需要的格式成为项目开发中首先要考虑的问题。 2、工业…

分布式组件 Nacos

1.在之前的文章写过的就不用重复写。 写一些没有写过的新东西 2.细节 2.1命名空间 &#xff1a; 配置隔离 默认&#xff1a; public &#xff08;默认命名空间&#xff09;:默认新增所有的配置都在public空间下 2.1.1 开发 、测试 、生产&#xff1a;有不同的配置文件 比如…

【ZYNQ】基于ZYNQ 7020的OPENCV源码交叉编译

目录 安装准备 检查编译器 安装OpenCV编译的依赖项 下载OpenCV源码 下载CMake 编译配置 编译器说明 参考链接 安装准备 使用的各个程序的版本内容如下&#xff1a; 类别 软件名称 软件版本 虚拟机 VMware VMware-workstation-full-15.5.0-14665864 操作系统 Ub…

【QT入门】 Qt实现自定义信号

往期回顾&#xff1a; 【QT入门】图片查看软件(优化)-CSDN博客 【QT入门】 lambda表达式(函数)详解-CSDN博客 【QT入门】 Qt槽函数五种常用写法介绍-CSDN博客 【QT入门】 Qt实现自定义信号 一、为什么需要自定义信号 比如说现在一个小需求&#xff0c;我们想要实现跨ui通信&a…