关于自定义Base64编解码的实现

什么是Base64

Base64编码是将字符串以每3个8比特(bit)的字节子序列拆分成4个6比特(bit)的字节(6比特有效字节,最左边两个永远为0,其实也是8比特的字节)子序列,再将得到的子序列查找Base64的编码索引表,得到对应的字符拼接成新的字符串的一种编码方式。

每个3位8比特数据拆分成4个6比特数据过程如下图所示:

关于自定义Base64编解码的实现

 

 

 注意事项

Base64编码后的数据大小必须是4的倍数,当转换后的数据大小不是4的倍数时可以用‘=’号或者其他符号代替。

代码实现

以下是我自定义的Base64编解码实现规则

编码部分

const char base64_table[] = "在此添加自定义base64编码规则";
std::string encode(std::string &src)
{
    char encodeData[10000000];
// 以3个字节为一组
    int data_len = src.length() / 3;
    // std::cout << src.length() << std::endl;
    // src的余数数据
    int data_add = src.length() % 3;
    int temp = 0;
    int tmp = 0;
    int n = 0;
    while (temp < data_len)
    {
        encodeData[n++] = base64_table[src[tmp] >> 2];
        encodeData[n++] = base64_table[(src[tmp] & 0x3) << 4 | src[tmp + 1] >> 4];
        encodeData[n++] = base64_table[(src[tmp + 1] & 0x0f) << 2 | src[tmp + 2] >> 6];
        encodeData[n++] = base64_table[src[tmp + 2] & 0x3f];
        tmp += 3;
        temp++;
    }
    // 余数为1,需要补齐2个=
    if (data_add == 1)
    {
        encodeData[n++] = base64_table[src[tmp] >> 2];
        encodeData[n++] = base64_table[(src[tmp] & 0x3) << 4];
        encodeData[n++] = '=';
        encodeData[n++] = '=';
        encodeData[n] = '\0';
    }
    // 余数为2,需要补齐1个=
    else if (data_add == 2)
    {
        encodeData[n++] = base64_table[src[tmp] >> 2];
        encodeData[n++] = base64_table[(src[tmp] & 0x3) << 4 | src[tmp + 1] >> 4];
        encodeData[n++] = base64_table[(src[tmp + 1] & 0xf) << 2];
        encodeData[n++] = '=';
        encodeData[n] = '\0';
    }
    else
    {
        encodeData[n] = '\0';
    }
    return std::string(encodeData);
}

解码部分

std::string decode(std::string &src)
{
    // 自定义base64解码表,以ASCII码值顺序存储,对应base64编码表
    const char decode_base64_table[] = {“自定义128位base64解码规则,以1128位ASCII码的顺序存储base64编码表中对应字符的位置”};
    int inputLen = src.length();
    // 计算解码后的数据长度
    int outputLen = inputLen / 4 * 3;
    unsigned buf = 0;
    unsigned bufSize = 0;
    if (inputLen % 4 == 0)
    {
        if (src[inputLen - 1] == '=')
            outputLen--;
        if (src[inputLen - 2] == '=')
            outputLen--;
    }
    else
    {
        switch (inputLen % 4)
        {
        case 1:
            throw std::invalid_argument("invalid input-1");
            return nullptr;
        case 2:
            outputLen++;
            break;
        case 3:
            outputLen += 2;
            break;
        }
    }
    std::string output(outputLen, '\0');
    int i = 0;
    for (uint8_t c : src)
    {
        if (c > 127 || c == '=')
            break;
        uint8_t sextet = decode_base64_table[c];
        if (sextet == 64)
        {
            throw std::invalid_argument("invalid base64 input-2");
            return nullptr;
        }
        buf = (buf << 6) + sextet;
        bufSize += 6;
        if (bufSize >= 8)
        {
            output[i++] = (buf >> (bufSize - 8));
            bufSize -= 8;
        }
    }
    return output;
}

 

原文链接:https://www.cnblogs.com/a1557944/p/17266792.html

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:关于自定义Base64编解码的实现 - Python技术站

(0)
上一篇 2023年4月18日
下一篇 2023年4月18日

相关文章

  • STL容器之queue

    是什么 循环队列, FIFO先进先出 怎么用 初始化 //C11 deque<int> deq{1,2,3,4,5}; //拷贝构造,可以拷贝deque queue<int> que(deq); //100个5 queue<int> que2(100,5); //运算符重载 que2 = que; 操作 //队尾添加元素 …

    C++ 2023年4月17日
    00
  • 网络框架重构之路plain2.0(c++23 without module) 综述

    最近互联网行业一片哀叹,这是受到三年影响的后遗症,许多的公司也未能挺过寒冬,一些外资也开始撤出市场,因此许多的IT从业人员加入失业的行列,而且由于公司较少导致许多人求职进度缓慢,很不幸本人也是其中之一。自从参加工作以来,一直都是忙忙碌碌,开始总认为工作只是为了更好的生活,但是一旦工作停下来后自己就觉得失去了一点什么,所以很少有像最近这两个月左右空闲的时光。人…

    C++ 2023年4月17日
    00
  • L1-087 机工士姆斯塔迪奥*(使用C++动态数组new暴力实现)

    L1-087 机工士姆斯塔迪奥 分数 20 全屏浏览题目 切换布局 作者 DAI, Longao单位 杭州百腾教育科技有限公司在 MMORPG《最终幻想14》的副本“乐欲之所瓯博讷修道院”里,BOSS 机工士姆斯塔迪奥将会接受玩家的挑战。 你需要处理这个副本其中的一个机制:N×M 大小的地图被拆分为了 N×M 个 1×1 的格子,BOSS 会选择若干行或/及…

    C++ 2023年4月18日
    00
  • 内存淘汰策略|页面置换算法对比总结

    在学习【操作系统】 【MySQL】【Redis】后,发现其都有一些缓存淘汰的策略,因此一篇小文章总结一下。 目前还没着笔,初略一想MySQL和操作系统应该都是使用的年轻代和老生代的改进策略,而Redis使用的是随机抽的策略。 MySQL MySQL中存在一个内存缓存池,Buffer Pool。里面存在着控制块和缓存的数据页(当然还有些其他缓存,比如:锁信息、…

    C++ 2023年4月18日
    00
  • C++动态分配(new)二维数组的若干方法

    写在前面 之前刷动态规划的题目,多需要用到二维数组(也许后面再优化成一维)。如果每次都按照给定数的范围直接声明为全局二维数组变量,又总觉得的不够优雅。查阅了一些网上的资料后,总结了一些使用方法,就写下这篇博文用以记录。 方法1——动态分配(new)一维数组,再强制类型转换为二维(个人使用,推荐指数:⭐⭐⭐⭐) 直接看例子 /** 假设需要根据两个string…

    C++ 2023年4月17日
    00
  • C++深拷贝与浅拷贝

    浅拷贝的问题 默认提供的拷贝构造就是浅拷贝,如果拷贝的对象中含有成员指针变量指向堆区中的内存空间,那么就会出现两个对象中的成员指针变量指向同一块堆区空间,当方法执行结束后,对象就会被释放,调用析构函数(析构函数中存在释放在堆区开辟的内存空间),就会存在一块内存空间被多次释放的问题。 解决办法 自己写拷贝构造,让拷贝构造后的对象中的成员指针变量指向一块新的内存…

    C++ 2023年4月25日
    00
  • C++的拓扑排序实现

    template<typename T = CString, typename _Data = CString> struct Union_node//!< 节点 { Union_node() :nColor(0) {} std::vector<Union_node*> vecNodeSon; T key;//!< 关键数…

    C++ 2023年4月22日
    00
  • 【Visual Leak Detector】配置项 SkipCrtStartupLeaks

    说明 使用 VLD 内存泄漏检测工具辅助开发时整理的学习笔记。本篇介绍 VLD 配置文件中配置项 SkipCrtStartupLeaks 的使用方法。同系列文章目录可见 《内存泄漏检测工具》目录 目录 说明 1. 配置文件使用说明 2. 设置是否忽略启动代码引起的内存泄漏 1. 配置文件使用说明 在程序中通过 #include “vld.h” 的方式检测内存…

    C++ 2023年4月18日
    00
合作推广
合作推广
分享本页
返回顶部