当前位置: 首页 > article >正文

c++ Base64编码

介绍

        Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。

        需要注意的是:标准的Base64并不适合直接放在URL里传输,因为URL编码器会把标准Base64中的“/”和“+”字符变为形如“%XX”的形式,而这些“%”号在存入数据库时还需要再进行转换,因为ANSI SQL中已将“%”号用作通配符

代码

        下面直接贴出代码:

#define BASE64_8BIT 3
#define BASE64_6BIT 4

static const char base64_dict[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
static const char base64_websafe_dict[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_=";

static const unsigned int base64_table[0x80] = 
{
    /*00-07*/0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    /*08-0f*/0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    /*10-17*/0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    /*18-1f*/0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    /*20-27*/0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    /*28-2f*/0xFF, 0xFF, 0xFF, 0x3e, 0xFF, 0xFF, 0xFF, 0x3f, //2 = '+' and '/'
    /*30-37*/0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, //8 = '0'-'7'
    /*38-3f*/0x3c, 0x3d, 0xFF, 0xFF, 0xFF, 0x40, 0xFF, 0xFF, //2 = '8'-'9' and '='
    /*40-47*/0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, //7 = 'A'-'G'
    /*48-4f*/0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, //8 = 'H'-'O'
    /*50-57*/0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, //8 = 'P'-'W'
    /*58-5f*/0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, //3 = 'X'-'Z'
    /*60-67*/0xFF, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, //7 = 'a'-'g'
    /*68-6f*/0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, //8 = 'h'-'o'
    /*70-77*/0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, //8 = 'p'-'w'
    /*78-7f*/0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF //3 = 'x'-'z'
};
static const unsigned int base64_websafe_table[0x80] = 
{
    /*00-07*/0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    /*08-0f*/0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    /*10-17*/0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    /*18-1f*/0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    /*20-27*/0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    /*28-2f*/0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3e, 0xFF, 0xFF, //1 = '-'
    /*30-37*/0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, //8 = '0'-'7'
    /*38-3f*/0x3c, 0x3d, 0xFF, 0xFF, 0xFF, 0x40, 0xFF, 0xFF, //2 = '8'-'9' and '='
    /*40-47*/0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, //7 = 'A'-'G'
    /*48-4f*/0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, //8 = 'H'-'O'
    /*50-57*/0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, //8 = 'P'-'W'
    /*58-5f*/0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0x3f, //4 = 'X'-'Z' and '_'
    /*60-67*/0xFF, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, //7 = 'a'-'g'
    /*68-6f*/0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, //8 = 'h'-'o'
    /*70-77*/0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, //8 = 'p'-'w'
    /*78-7f*/0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF //3 = 'x'-'z'
};

#define base64_encode_length(A) (((A + BASE64_8BIT - 1) / BASE64_8BIT) * BASE64_6BIT + 1)
#define base64_decode_length(A) (((A + BASE64_6BIT - 1) / BASE64_6BIT) * BASE64_8BIT)

static size_t base64_encode_impl(char* dest, const char* src, size_t size, const char* dict)
{
    unsigned char* usrc = (unsigned char*) src;
    unsigned char* udest = (unsigned char*) dest;
    size_t destsize = 0;

    while (size >= 1)
    {
        size_t blocksize = __min(size, BASE64_8BIT);
        // Encode inputs...
        unsigned char n1, n2 = 0, n3 = 0, n4 = 0;
        switch (blocksize)
        {
        case 3:
            n4 = (usrc[2] & 0x3f);
            n3 = ((usrc[2] & 0xc0) >> 6);
        case 2:
            n3 |= ((usrc[1] & 0x0f) << 2);
            n2 = ((usrc[1] & 0xf0) >> 4);
        case 1:
            n2 |= ((usrc[0] & 0x03) << 4);
            n1 = ((usrc[0] & 0xfc) >> 2);
            break;

        default:
            break;
        }
        usrc += blocksize;
        size -= blocksize;

        // Padding...
        switch (blocksize)
        {
        case 1:
            n3 = 64;
        case 2:
            n4 = 64;
        case 3:
            break;

        default:
            break;
        }

        // 4 outputs...
        *udest++ = dict[n1];
        *udest++ = dict[n2];
        *udest++ = dict[n3];
        *udest++ = dict[n4];
        destsize += BASE64_6BIT; //4
    }
    return destsize;
}

static size_t base64_decode_impl(char* dest, const char* src, size_t size, const unsigned int* base64table)
{
    if (size < BASE64_6BIT || size % BASE64_6BIT != 0)
        return 0;

    unsigned char* usrc = (unsigned char*) src;
    unsigned char* udest = (unsigned char*) dest;
    size_t destsize = 0;

    while (size >= 1)
    {
        // 4 inputs...
        unsigned char in1 = *usrc++;
        unsigned char in2 = *usrc++;
        unsigned char in3 = *usrc++;
        unsigned char in4 = *usrc++;
        size -= BASE64_6BIT; //4

        // Convert ascii to base16...
        in1 = base64table[in1];
        in2 = base64table[in2];
        in3 = base64table[in3];
        in4 = base64table[in4];

        // 3 outputs...
        *udest++ = ((in1 & 0x3f) << 2) | ((in2 & 0x30) >> 4);
        *udest++ = ((in2 & 0x0f) << 4) | ((in3 & 0x3c) >> 2);
        *udest++ = ((in3 & 0x03) << 6) | (in4 & 0x3f);
        destsize += BASE64_8BIT; //3

        // Padding...
        if (in4 == 64)
        {
            --destsize;
            if (in3 == 64)
            {
                --destsize;
            }
        }
    }
    return destsize;
}

std::string base64_encode(const char* s, size_t len)
{
    std::string temp;
    if (!s || len == 0)
    {
        return temp;
    }
    temp.resize(base64_encode_length(len));
    size_t output_size = base64_encode_impl(&(temp[0]), s, len, base64_dict);
    temp.resize(output_size);
    return temp;
}

std::string base64_decode(const char* s, size_t len)
{
    std::string temp;
    if (!s || len == 0)
    {
        return temp;
    }
    temp.resize(base64_decode_length(len));
    size_t output_size = base64_decode_impl(&(temp[0]), s, len, base64_table);
    temp.resize(output_size);
    return temp;
}

base64_encode 是编码

base64_decode 是解码


http://www.kler.cn/a/533362.html

相关文章:

  • 深度剖析八大排序算法
  • 智慧园区系统集成解决方案提升管理效率与智能化水平的新探索
  • [创业之路-273]:《发现利润区》的主要内容与核心思想
  • 【1】快手面试题整理
  • javaEE-8.JVM(八股文系列)
  • 小程序设计和开发:如何研究同类型小程序的优点和不足。
  • 使用python实现与本地ollama部署的deepseek对话
  • p5r预告信生成器API
  • Windows Docker笔记-安装docker
  • C++ 入门速通-第5章【黑马】
  • iOS 老项目适配 #Preview 预览功能
  • python基础入门:2.1变量与基本数据类型
  • 音频录制一般在什么情况下会选择保存为PCM?什么情况会选择保存为WAV?
  • torchtext.get_tokenizer
  • C32.【C++ Cont】静态实现双向链表及STL库的list
  • 蓝桥杯整数删除(优先队列pair,模拟链表)
  • 今日AI和商界事件(2025-02-05)
  • punkt缺失问题
  • 定时任务单线程消费 redis 中数据导致消费能力不足
  • Docker深度解析:部署 SpringBoot 项目
  • TensorFlow是个啥玩意?
  • 学习threejs,pvr格式图片文件贴图
  • 108,【8】 buuctf web [网鼎杯 2020 青龙组]AreUSerialz
  • 每日Attention学习18——Grouped Attention Gate
  • 探索巨控GRM240系列远程模块的强大功能:物联应用新选择
  • deepseek、qwen等多种模型本地化部署