使用C++ jsoncons库转换CBOR为JSON时字节串输出异常求助
问题根因
JSON标准本身没有原生的二进制数据类型,jsoncons库默认会将CBOR解码得到的字节串(byte string)类型编码为Base64URL格式的字符串输出,而cbor.me工具是直接将二进制字节转换为十六进制字符串展示,二者默认序列化规则不同,所以输出结果有差异,不是代码逻辑错误。
解决方法
如果需要得到和cbor.me一致的十六进制格式输出,可以手动识别并转换字节串类型的字段,步骤如下:
- 先判断json节点是否为字节串类型,调用
is_byte_string()方法即可 - 取出原始字节数组,转换为大写十六进制字符串后再输出
完整示例代码:
#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
相关产品推荐
相关产品推荐

