IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C语言base64实现 -> 正文阅读

[C++知识库]C语言base64实现

1. base64 原理

  • Base64 算法的原理,是将输入流中的字节按每 3 个分为一组,然后 每次取 6 个比特,将其转换成表格中对应的数据,一直重复到没有剩余的字符为止,转换表格如下:
    base64编码表
  • 上面就是Base64的索引表,字符选用了"A-Z、a-z、0-9、+、/" 64个可打印字符,这是标准的Base64协议规定。在日常使用中还会看到“=”或“==”号出现在Base64的编码结果中,“=”在此是作为填充字符出现。
  • 示例说明
    以下图的表格为示例,具体分析当字符 占 全 \color{gold}{占全} 时的过程。
    show table1
    当位数 不 足 \color{gold}{不足} 的时候。
    show table2

2.base64实现

核心原理
1. 获取第一个字符8个 bit 的前6位,作为 base64编码的第一位;
2. 获取第一个字符8个 bit 的后2位和第二个字符8个 bit 的前4位,作为 base64 编码的第二位;
3. 获取第二个字符8个 bit 的后4位和第三个字符8个 bit 的前2位,作为 base64编码的第三位;
4. 获取第三个字符8个 bit 的后6位,作为 base64编码的第四位;
如此3个字符可编码 base64 为4个字符,当位数不够时补 0 来满足一个字符,且要实现编码后的位数为4的倍数,不足的用 “=” 代替。

方法一

利用 ASCII 码与 base64 码进行转换的方法

  • base64是由 A ~ Z , a ~ z , 1 ~ 9 , + , / \color{red} {A{\sim}Z , a{\sim}z ,1{\sim}9, + , / } AZ,az,19,+,/构成,其编码位 0 ~ 64 \color{red}{0{\sim}64} 064,通过对比 A S C I I \color{red} { ASCII } ASCII 码表可找到对应数字关系

1.编码

  • 设传入字符为c,c语言中 char 字符以ASCII码存储,将其变为真正的ASCII码对应的字符即可。
    a :当 ASCII 码小于 25(0~25) 时,return ( ‘A’ + c );26是对应的前26个 base (A~Z)码
    b :当 ASCII 码在26到51(26~51)之间时,return ( ‘a’ + ( c - 26 ));此时是接下来的26个 base(a~z)码
    c :当 ASCII 码在52到61(52~61)之间时,return ( ‘0’ + ( c - 52 ));此时是接下来的10个 base(0~9)码
    d :当 ASCII 码为62(62)时,return ‘+’
    e :当 ASCII 码为63(63)时,return ‘/’
    f :当 ASCII 码大于63 (64~…)时, 此时c = c - c/64*64;循环以上步骤;

2.解码

  • 编码传入字符m,base64 的字符,将其还原为真正的 ASCII 码即可。
    a :当输入字符在A~Z间return ( m - ‘A’ )
    b :当输入字符在a~z之间return ( 26 + m - ‘a’ )
    c : 当输入的字符在0~9之间return ( 52 + m - ‘0’ )
    d :当输入的字符为 “+”return 62
    e :当输入字符为 “/”return 63
if(*m>='A'&&*m<='Z')
	{
	 *m-='A';
	 continue;
	}
	if(*m>='a'&&*m<='z')
	{
	 *m-='a';
	 *m+=26;
	 continue;
	}
	if(*m=='+')
	{
	 *m=62;
	 continue;
	}
	if(*m=='/')
	{
	 *m=63;
	 continue;
	}
	if(*m=='=')
	{
	 *m=0;
	 continue;
	}
	*m-='0';
	*m+=52;

参考代码

方法二

直接对字符串进行转换

	//base64.h
#pragma once
#ifndef BASE64_H_INCLUDED
#define BASE64_H_INCLUDED

#include <stdio.h>
#include <stdlib.h>
#include<windows.h>
#include <string.h>

char* base64_encode(char* binData, char* base64, int binLength);
char* base64_decode(char const* base64Str, char* debase64Str, int encodeStrLen);
void Menu();
void decode();
void encode();

#endif // BASE64_H_INCLUDED
	//base64.c
#pragma warning(disable:4996)
#include"base64.h"

char base64char[] = {
        'A','B','C','D','E','F','G','H','I','J',
        'K','L','M','N','O','P','Q','R','S','T',
        'U','V','W','X','Y','Z','a','b','c','d',
        'e','f','g','h','i','j','k','l','m','n',
        'o','p','q','r','s','t','u','v','w','x',
        'y','z','0','1','2','3','4','5','6','7',
        '8','9','+', '/', '\0'
};

char c;

void Menu()
{
    printf("***************\n");
    printf("*1、base64加密\n");
    printf("*2、base64解密\n");
    printf("*3、退出程序\n");
    printf("***************\n");
}

void encode()
{
    do
    {
        system("cls");
        printf(" ---- base64_encode ----\n\n");
        char soursedata[1024];
        scanf("%s", &soursedata);
        
        getchar();  //吸收缓冲区的换行符
        char* result = (char*)malloc(sizeof(char) * 1024);	//申请返回字符串空间
        memset(result, 0, sizeof(char) * 1024);		//初始化字符串空间
        
        printf("\t\t\n%s\n", base64_encode(soursedata, result, (int)strlen(soursedata)));
        printf("\nWhether to continue:(Y/N)\n");	//是否继续进行操作
    } while ((c = getch())!='N'&& c != 'n');
}

void decode()
{
    do {
        system("cls");
        printf(" ---- base64_dncode ----\n\n");
        char soursedata[1024];
        scanf("%s", &soursedata);
        getchar();  //吸收缓冲区的换行符
        
        char* result = (char*)malloc(sizeof(char) * 1024);
        memset(result, 0, sizeof(char) * 1024);
        
        printf("\t\t\n%s\n",base64_decode((char const*)soursedata, result, (int)strlen(soursedata)));
        printf("\nWhether to continue:(Y/N)\n");
    } while ((c = getch()) != 'N' && c != 'n');
}

char* base64_encode(char* binData, char* base64, int binLength)
{
    int i = 0;
    int j = 0;
    int current = 0;
    for (i = 0; i < binLength; i += 3) {
        //获取第一个6位
        current = (*(binData + i) >> 2) & 0x3F;
        *(base64 + j++) = base64char[current];
        //获取第二个6位的前两位
        current = (*(binData + i) << 4) & 0x30;
        //如果只有一个字符,那么需要做特殊处理
        if (binLength <= (i + 1)) {
            *(base64 + j++) = base64char[current];
            *(base64 + j++) = '=';
            *(base64 + j++) = '=';
            break;
        }
        //获取第二个6位的后四位
        current |= (*(binData + i + 1) >> 4) & 0xf;
        *(base64 + j++) = base64char[current];
        //获取第三个6位的前四位
        current = (*(binData + i + 1) << 2) & 0x3c;
        if (binLength <= (i + 2)) {
            *(base64 + j++) = base64char[current];
            *(base64 + j++) = '=';
            break;
        }
        //获取第三个6位的后两位
        current |= (*(binData + i + 2) >> 6) & 0x03;
        *(base64 + j++) = base64char[current];
        //获取第四个6位
        current = *(binData + i + 2) & 0x3F;
        *(base64 + j++) = base64char[current];
    }
    *(base64 + j) = '\0';
    return base64;
}

char* base64_decode(char const* base64Str, char* debase64Str, int encodeStrLen)
{
    int i = 0;
    int j = 0;
    int k = 0;
    char temp[4] = "";

    for (i = 0; i < encodeStrLen; i += 4) {
        for (j = 0; j < 64; j++) {
            if (*(base64Str + i) == base64char[j]) {
                temp[0] = j;
            }
        }
        
        for (j = 0; j < 64; j++) {
            if (*(base64Str + i + 1) == base64char[j]) {
                temp[1] = j;
            }
        }

        for (j = 0; j < 64; j++) {
            if (*(base64Str + i + 2) == base64char[j]) {
                temp[2] = j;
            }
        }

        for (j = 0; j < 64; j++) {
            if (*(base64Str + i + 3) == base64char[j]) {
                temp[3] = j;
            }
        }

        *(debase64Str + k++) = ((temp[0] << 2) & 0xFC) | ((temp[1] >> 4) & 0x03);
        if (*(base64Str + i + 2) == '=')
            break;

        *(debase64Str + k++) = ((temp[1] << 4) & 0xF0) | ((temp[2] >> 2) & 0x0F);
        if (*(base64Str + i + 3) == '=')
            break;

        *(debase64Str + k++) = ((temp[2] << 6) & 0xF0) | (temp[3] & 0x3F);
    }
    return debase64Str;
}

	//main.c
#pragma warning(disable:4996)
#include"base64.h"

int main()
{
    Menu();
    char a;
    scanf("%c", &a);
    switch (a)
    {
    case '1':
        encode();
        break;
    case '2':
        decode();
        break;
    case '3':
        exit(0);
    }
    return 0;
}
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-01 15:31:12  更:2022-05-01 15:31:19 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/21 5:57:27-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码