利用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”文件,以免打开文件时失败。

运行之后得到两个文件

 

也是包成功的啊。 

评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大筒木老辈子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值