为何Python的CBOR库编码结果与RIOT OS的NanoCBOR库存在差异
问题原因分析
两个编码结果的核心差异是CBOR的map结构编码模式不同:
- 从RIOT OS的NanoCBOR库输出的编码开头为
\xbf、结尾为\xff:这是CBOR规范定义的不定长map格式,0xbf是不定长map的起始标记,0xff是CBOR结构终止符,用来标识不定长map的结束边界 - Python CBOR库默认输出的编码开头为
\xa4:这是定长map格式,0xa4的含义是「map类型,包含4个键值对」,编码时会提前声明结构长度,没有尾部的终止符,所以无法匹配目标系统的解析逻辑
NanoCBOR库默认使用不定长模式编码集合类结构,且部分版本的NanoCBOR解码逻辑仅适配不定长结构输入,因此定长编码的报文会被判定为非法。
解决方法
使用cbor2库即可直接生成符合要求的不定长CBOR编码,示例代码如下:
import cbor2 # 原始业务数据 data = { 'apn': 'censored', 'support_data_mode': False, 'data_usr_name': 'censored', 'data_password': 'censored' } # 编码时指定集合类结构使用不定长模式 encoded_data = cbor2.dumps(data, write_as_indefinite=True) # 验证输出结果 print(encoded_data) # 输出和RIOT系统返回的编码完全一致:b'\xbfcapnjcensoredqsupport_data_mode\xf4mdata_usr_namedcensoredmdata_passworddcensored\xff'
如果使用的是旧版cbor库,也可以手动修改编码字节实现兼容:
import cbor data = { 'apn': 'censored', 'support_data_mode': False, 'data_usr_name': 'censored', 'data_password': 'censored' } # 先得到默认定长编码 definite_enc = cbor.dumps(data) # 替换开头的定长map标记为不定长标记,末尾追加终止符 indefinite_enc = b'\xbf' + definite_enc[1:] + b'\xff'
内容的提问来源于stack exchange,提问作者Marcin Szymczyk
相关产品推荐
相关产品推荐

