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

news2024/11/15 11:21:14

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.coloradmin.cn/o/1539348.html

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

相关文章

实用工具推荐:适用于 TypeScript 网络爬取的常用爬虫框架与库

随着互联网的迅猛发展&#xff0c;网络爬虫在信息收集、数据分析等领域扮演着重要角色。而在当前的技术环境下&#xff0c;使用TypeScript编写网络爬虫程序成为越来越流行的选择。TypeScript作为JavaScript的超集&#xff0c;通过类型检查和面向对象的特性&#xff0c;提高了代…

武汉星起航电商:跨境创业领航者,一站式服务助您轻松启航

在当今全球化的浪潮中&#xff0c;跨境电商以其独特的优势&#xff0c;成为越来越多创业者的首选。然而&#xff0c;如何在这个竞争激烈的市场中脱颖而出&#xff0c;实现业务的快速增长&#xff0c;却成为摆在创业者面前的一大难题。武汉星起航电子商务有限公司&#xff0c;正…

【go从入门到精通】if else 条件控制

作者简介&#xff1a; 高科&#xff0c;先后在 IBM PlatformComputing从事网格计算&#xff0c;淘米网&#xff0c;网易从事游戏服务器开发&#xff0c;拥有丰富的C&#xff0c;go等语言开发经验&#xff0c;mysql&#xff0c;mongo&#xff0c;redis等数据库&#xff0c;设计模…

面试算法-82-不同路径

题目 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。 问总共有多少条不同的路径&#xff1f; …

OpenHarmony实战开发-手写板应用开发操作流程

分布式手写板&#xff08;ArkTS&#xff09; 介绍 本篇Codelab使用设备管理及分布式键值数据库能力&#xff0c;实现多设备之间手写板应用拉起及同步书写内容的功能。操作流程&#xff1a; 设备连接同一无线网络&#xff0c;安装分布式手写板应用。进入应用&#xff0c;点击…

皓学IT:WEB06_ EL表达式JSTL标签库

一、EL表达式 1.1.特点 是一个由java开发的工具包 用于从特定域对象中读取并写入到响应体开发任务&#xff0c;不能向域对象中写入。 EL工具包自动存在Tomcat的lib中&#xff08;el-api.jar&#xff09;&#xff0c;开发是可以直接使用&#xff0c;无需其他额外的包。 标准…

亚马逊云科技:企业如何开启生成式AI之旅?

如果要评选最近两年全球科技行业最热门的细分领域&#xff0c;那么生成式AI绝对会以遥遥领先的票数成为当仁不让的冠军。 然而眼见生成式AI发展得如火如荼&#xff0c;越来越多的企业却陷入了深深的焦虑&#xff1a;应该如何开启生成式AI之旅&#xff1f;又该怎样搭建大模型&am…

33-Java服务定位器模式 (Service Locator Pattern)

Java服务定位器模式 实现范例 服务定位器模式&#xff08;Service Locator Pattern&#xff09;用于想使用 JNDI 查询定位各种服务的时候考虑到为某个服务查找 JNDI 的代价很高&#xff0c;服务定位器模式充分利用了缓存技术在首次请求某个服务时&#xff0c;服务定位器在 JNDI…

网站引入 Prism,使得代码高亮显示,并一键复制代码块

曾几何时&#xff0c;苦恼如何将本地写好的博文&#xff0c;更好的展示读者屏幕前&#xff1f;若只是简简单单的文章&#xff0c;其实还是很好的解决它的&#xff01;可是&#xff0c;像我们这样写技术文章&#xff08;有点牵强&#xff09;的&#xff0c;在文章内容嵌入部分代…

【C++庖丁解牛】二叉搜索树(Binary Search Tree,BST)

&#x1f341;你好&#xff0c;我是 RO-BERRY &#x1f4d7; 致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 &#x1f384;感谢你的陪伴与支持 &#xff0c;故事既有了开头&#xff0c;就要画上一个完美的句号&#xff0c;让我们一起加油 目录 1. 二叉搜索树概念2. 二叉…

IDEA 下载依赖包源码报错 Cannot download sources Sources not found for:XXX

最近在做一个功能的时候想看一个库的源码&#xff0c;结果源码下不下来&#xff0c;报Cannot download sources Sources not found for:XXX,网上搜了半天&#xff0c;也找不到靠谱的结论 后来想了下&#xff0c;应该是镜像那边出了问题&#xff0c;把镜像一删&#xff0c;源码…

EPO企业生产运营数智化平台助力制造企业迈向智能制造

随着“中国制造2025”和工业4.0的不断推进&#xff0c;越来越多的制造企业准备迈入智能制造和智慧制造领域&#xff0c;实现数智化管理。企业通过搭建EPO企业生产运营平台&#xff0c;结合自身业务现状和数字化需求&#xff0c;从各个业务场景、部门人员、产品组成等方面进行分…

(一)、Doris安装使用(基于Doris 2.0.6)

第 1 章Doris简介 1.1、 Doris 概述 ​ Apache Doris由百度大数据部研发&#xff08;之前叫百度 Palo&#xff0c;2018年贡献到 Apache 社区后&#xff0c;更名为 Doris&#xff09;&#xff0c;在百度内部&#xff0c;有超过200个产品线在使用&#xff0c;部署机器超过1000台…

国际品牌交期长 雷卯来帮忙

在当今的电子元器件市场中&#xff0c;防静电电子元器件的需求日益增长。无论是通信安防、医疗、消费类电子、照明行业、航空航天还是汽车电子等领域都会使用到防静电产品&#xff0c;使得防静电电子元器件的需求也呈现出爆发式的增长。在这一市场中&#xff0c;雷卯品牌凭借其…

Chain of Note-CoN增强检索增强型语言模型的鲁棒性

Enhancing Robustness in Retrieval-Augmented Language Models 检索增强型语言模型&#xff08;RALMs&#xff09;在大型语言模型的能力上取得了重大进步&#xff0c;特别是在利用外部知识源减少事实性幻觉方面。然而&#xff0c;检索到的信息的可靠性并不总是有保证的。检索…

六.排序nb三人组(快速排序)

目录 17-快速排序原理介绍 思路: 18-快速排序代码实现 19-快速排序代码实现2 缺点: 递归的限度: 17-快速排序原理介绍 思路: --先找一个变量把 5(第一个数) 存起来, (两个箭头分别是left , right) --左边有一个空位, 发现左边的位置是给比5小的值准备的. --找比5小的值…

算法体系-12 第 十二 二叉树的基本算法 下

一 实现二叉树的按层遍历 1.1 描述 1&#xff09;其实就是宽度优先遍历&#xff0c;用队列 2&#xff09;可以通过设置flag变量的方式&#xff0c;来发现某一层的结束&#xff08;看题目&#xff09;看下边的第四题解答 1.2 代码 public class Code01_LevelTraversalBT {publ…

【LabVIEW FPGA入门】FPGA不同传递数据方法比较

数据共享方法的选择应基于应用的需要。根据应用程序的重要特性&#xff0c;所讨论的任何一种方法都可能是合适的。 传输方法FPGA资源损耗&#xff1f;不同时钟源之间传递数据&#xff1f;新数据通知&#xff1f;常见用途变量逻辑片是是否提取最新数据存储器存储器是否否提取最新…

ubuntu20.04_PX4_1.13

说在前面&#xff1a;&#xff08;最好找一个干净的Ubuntu系统&#xff09;如果配置环境的过程中出现很多编译的错误或者依赖冲突&#xff0c;还是建议新建一个虚拟机&#xff0c;或者重装Ubuntu系统&#xff0c;这样会避免很多麻烦&#x1f490; &#xff0c; 安装PX4 1.13.2 …

学习刷题-12

3.22 hw机试【双指针】 Leetcode674 最长连续递增序列 给定一个未经排序的整数数组&#xff0c;找到最长且 连续递增的子序列&#xff0c;并返回该序列的长度。 双指针 一个慢指针一个快指针 慢指针记录递增子序列起点&#xff0c;快指针去寻找还在当前递增子序列的最后一…