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

使用C++ jsoncons库转换CBOR为JSON时字节串输出异常求助

问题根因

JSON标准本身没有原生的二进制数据类型,jsoncons库默认会将CBOR解码得到的字节串(byte string)类型编码为Base64URL格式的字符串输出,而cbor.me工具是直接将二进制字节转换为十六进制字符串展示,二者默认序列化规则不同,所以输出结果有差异,不是代码逻辑错误。

解决方法

如果需要得到和cbor.me一致的十六进制格式输出,可以手动识别并转换字节串类型的字段,步骤如下:

  1. 先判断json节点是否为字节串类型,调用is_byte_string()方法即可
  2. 取出原始字节数组,转换为大写十六进制字符串后再输出

完整示例代码:

#include <jsoncons/json.hpp>
#include <jsoncons_ext/cbor/cbor.hpp>
#include <string>
#include <sstream>
#include <iomanip>

using namespace jsoncons;

// 字节数组转十六进制字符串工具函数
std::string bytes_to_hex(const std::vector<uint8_t>& bytes) {
    std::ostringstream oss;
    oss << std::hex << std::uppercase << std::setfill('0');
    for (uint8_t b : bytes) {
        oss << std::setw(2) << static_cast<int>(b);
    }
    return oss.str();
}

// 递归处理json中的所有字节串字段,替换为十六进制字符串
void convert_byte_string_to_hex(json& j) {
    if (j.is_byte_string()) {
        auto bytes = j.as<std::vector<uint8_t>>();
        j = bytes_to_hex(bytes);
    } else if (j.is_object() || j.is_array()) {
        for (auto& val : j.array_range()) {
            convert_byte_string_to_hex(val);
        }
        for (auto& kv : j.object_range()) {
            convert_byte_string_to_hex(kv.value());
        }
    }
}

int main() {
    const std::vector<uint8_t> data1 = {  0xa4, 0x01, 0x58 , 0x65 , 0x83 , 0x43 , 0xa1 , 0x01
                                         , 0x0a , 0xa1 , 0x05 , 0x4d , 0xba , 0xe3 , 0xff , 0x8c
                                         , 0x34 , 0x9e , 0x98 , 0x15 , 0xe1 , 0x79 , 0x85 , 0x4c
                                         , 0xec , 0x58 , 0x4e , 0x7b , 0x3e , 0x19 , 0x05 , 0x32
                                         , 0x00 , 0x79 , 0x72 , 0x8f , 0x48 , 0xe4 , 0xe0 , 0x12
                                         , 0x96 , 0xb2 , 0xd9 , 0x84 , 0xfd , 0xd5 , 0x62 , 0x7e
                                         , 0x42 , 0x6d , 0x68 , 0xe9 , 0xde , 0xe2 , 0xf2 , 0xc4
                                         , 0xef , 0xe6 , 0xf2 , 0x72 , 0x76 , 0xad , 0xee , 0xbf
                                         , 0x17 , 0x06 , 0x91 , 0xca , 0x15 , 0x7f , 0x09 , 0x45
                                         , 0x08 , 0x67 , 0xdc , 0xeb , 0x7d , 0xf8 , 0xeb , 0xea
                                         , 0x02 , 0x01 , 0x99 , 0x7a , 0xc0 , 0xc6 , 0x7b , 0x17
                                         , 0xf2 , 0x2e , 0xd5 , 0x76 , 0x9d , 0x88 , 0xc0 , 0xfc
                                         , 0x20 , 0x41 , 0x7d , 0x9d , 0x8a , 0x17 , 0x91 , 0xec
                                         , 0x01 , 0x06 , 0x1a , 0x61 , 0x73 , 0x19 , 0x72 , 0x07
                                         , 0x01 , 0x08 , 0xa1 , 0x01 , 0xa2 , 0x01 , 0x04 , 0x20
                                         , 0x50 , 0xf7 , 0x77 , 0xd3 , 0xb7 , 0x82 , 0x01 , 0xef
                                         , 0x29 , 0x49 , 0x09 , 0xde , 0xe0 , 0x8b , 0x7a , 0xd3
                                         , 0x59};

    json j = cbor::decode_cbor<json>(data1);
    // 转换所有字节串为十六进制字符串
    convert_byte_string_to_hex(j);
    // 打印结果和cbor.me输出完全匹配
    std::cout << "(1)\n" << pretty_print(j) << "\n\n";
    return 0;
}

如果只需要单独获取指定字段的十六进制值,不需要修改整个json结构,也可以直接单独取值转换:

// 取键为1的字段的十六进制值
auto field1 = j["1"].as<std::vector<uint8_t>>();
std::cout << "键1的十六进制值:" << bytes_to_hex(field1) << std::endl;

// 取键为-1的字段的十六进制值
auto field_neg1 = j["8"]["1"]["-1"].as<std::vector<uint8_t>>();
std::cout << "键-1的十六进制值:" << bytes_to_hex(field_neg1) << std::endl;

内容的提问来源于stack exchange,提问作者Knöt

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 13:45:04