You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++中如何实现Hex与Text模式Base64编码结果互转

C++ 实现Base64两种编码模式对齐方案

问题背景

开发对接多接口时会遇到Base64编码逻辑不一致的问题:两个对接API分别采用Hex模式、Text模式处理Base64编码,需要对齐编码逻辑保证跨接口结果统一。
两种模式对相同输入字符串的编码结果差异如下:

fb95 <- HEX -- BASE64-> +5U=
fb95 <- TEXT -- BASE64-> ZmI5NQ==

两种模式的核心差异:

  • Text模式:直接取输入字符串每个字符的ASCII字节作为Base64编码的输入字节流
  • Hex模式:先将输入的十六进制字符串按每2个字符解析为1个原始字节,再将解析得到的字节流作为Base64编码的输入源

待实现目标

满足以下任意一种转换即可实现逻辑对齐:

  1. 将std::string text("fb95");转换为Hex模式要求的原始字节形式,经Base64编码后得到结果+5U=
  2. 将Text模式输出的Base64结果std::string b64("ZmI5NQ==");直接转换为Hex模式对应的Base64结果+5U=

可行实现方案

两种目标本质逻辑相通,核心是先完成十六进制字符串到原始字节流的解析,再对字节流做标准Base64编码即可,以下是无第三方依赖的标准C++实现:
首先实现通用工具函数:

#include <string>
#include <stdexcept>
#include <cstdint>
#include <cstring>

// 十六进制字符转对应数值
inline uint8_t hex_char_to_val(char c) {
    if (c >= '0' && c <= '9') return c - '0';
    if (c >= 'a' && c <= 'f') return 10 + c - 'a';
    if (c >= 'A' && c <= 'F') return 10 + c - 'A';
    throw std::invalid_argument("invalid hex character");
}

// 十六进制字符串转原始字节流
std::string hex_str_to_bytes(const std::string& hex_str) {
    if (hex_str.size() % 2 != 0) {
        throw std::invalid_argument("hex string length must be even");
    }
    std::string res;
    res.reserve(hex_str.size() / 2);
    for (size_t i = 0; i < hex_str.size(); i += 2) {
        uint8_t high = hex_char_to_val(hex_str[i]);
        uint8_t low = hex_char_to_val(hex_str[i+1]);
        res.push_back(static_cast<char>((high << 4) | low));
    }
    return res;
}

// 标准Base64编码表
const char BASE64_TABLE[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

// 原始字节流转标准Base64字符串
std::string bytes_to_base64(const std::string& bytes) {
    std::string res;
    size_t len = bytes.size();
    res.reserve((len + 2) / 3 * 4);
    for (size_t i = 0; i < len; ) {
        uint32_t octet_a = i < len ? static_cast<uint8_t>(bytes[i++]) : 0;
        uint32_t octet_b = i < len ? static_cast<uint8_t>(bytes[i++]) : 0;
        uint32_t octet_c = i < len ? static_cast<uint8_t>(bytes[i++]) : 0;
        uint32_t triple = (octet_a << 16) | (octet_b << 8) | octet_c;
        
        res.push_back(BASE64_TABLE[(triple >> 18) & 0x3F]);
        res.push_back(BASE64_TABLE[(triple >> 12) & 0x3F]);
        res.push_back(BASE64_TABLE[(triple >> 6) & 0x3F]);
        res.push_back(BASE64_TABLE[triple & 0x3F]);
    }
    // 补末尾等号
    if (len % 3 == 1) {
        res[res.size()-1] = '=';
        res[res.size()-2] = '=';
    } else if (len % 3 == 2) {
        res[res.size()-1] = '=';
    }
    return res;
}

// 标准Base64字符串解码为原始字节流(用于方案2)
std::string base64_to_bytes(const std::string& b64_str) {
    static int8_t rev_table[256];
    static bool table_init = false;
    if (!table_init) {
        memset(rev_table, -1, sizeof(rev_table));
        for (int i = 0; i < 64; i++) {
            rev_table[static_cast<uint8_t>(BASE64_TABLE[i])] = i;
        }
        table_init = true;
    }
    std::string res;
    size_t len = b64_str.size();
    res.reserve(len / 4 * 3);
    for (size_t i = 0; i < len; ) {
        uint32_t sextet_a = b64_str[i] == '=' ? 0 & i++ : rev_table[static_cast<uint8_t>(b64_str[i++])];
        uint32_t sextet_b = b64_str[i] == '=' ? 0 & i++ : rev_table[static_cast<uint8_t>(b64_str[i++])];
        uint32_t sextet_c = b64_str[i] == '=' ? 0 & i++ : rev_table[static_cast<uint8_t>(b64_str[i++])];
        uint32_t sextet_d = b64_str[i] == '=' ? 0 & i++ : rev_table[static_cast<uint8_t>(b64_str[i++])];
        uint32_t triple = (sextet_a << 18) | (sextet_b << 12) | (sextet_c << 6) | sextet_d;
        
        if (sextet_c != -1) res.push_back(static_cast<char>((triple >> 16) & 0xFF));
        if (sextet_d != -1) res.push_back(static_cast<char>((triple >> 8) & 0xFF));
    }
    return res;
}

方案1实现(原始文本转Hex模式Base64)

直接将输入的文本作为十六进制字符串解析为字节流,再做Base64编码即可:

std::string text_to_hex_b64(const std::string& text) {
    std::string bytes = hex_str_to_bytes(text);
    return bytes_to_base64(bytes);
}

// 测试:传入"fb95",返回结果为"+5U="

方案2实现(Text模式Base64转Hex模式Base64)

先将Text模式的Base64解码为原始ASCII字节流(即原始输入的十六进制字符串),再复用方案1的逻辑即可:

std::string text_b64_to_hex_b64(const std::string& text_b64) {
    std::string origin_text = base64_to_bytes(text_b64);
    return text_to_hex_b64(origin_text);
}

// 测试:传入"ZmI5NQ==",返回结果为"+5U="

注意:如果项目中已经引入了OpenSSL、Boost等自带Base64、Hex编解码能力的库,可以直接复用库的对应接口替换上述自实现的工具函数,逻辑完全一致。

内容的提问来源于stack exchange,提问作者Szymon Ożóg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 04:09:29