使用Cbor::XS解码CBOR后,Data::Dumper输出顺序不符如何解决?
如何让Perl的CBOR::XS解码后保留CBOR原始键顺序
问题描述
使用Perl的CBOR::XS模块解码CBOR十六进制字符串后,用Data::Dumper打印数据时,发现哈希的键顺序与原始CBOR字节中的顺序不一致。
原始代码:
use CBOR::XS; my $hex_data = "84AA1A300000031901001A10000002031A1000000A011A700001F7011A600003F11B0000023D19D43C001A600003F0001A800003EE41011A900003EF51300F310D300B0603550403130446616B651A600002BD1B00000189DB1BABD91A2000000142020340A040"; my $data = pack "H*", $hex_data; my $decoded_data = CBOR::XS::decode_cbor($data); use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper($decoded_data);
期望输出的哈希键顺序与CBOR原始字节顺序一致,但实际输出的哈希键被自动重新排序。
解决方案
CBOR::XS支持通过解码选项让哈希保留原始顺序,核心是依赖Tie::IxHash模块实现有序哈希,并配合解码参数和Data::Dumper的设置。
步骤
- 安装
Tie::IxHash模块(执行cpanm Tie::IxHash完成安装) - 调用
decode_cbor时传入{ ordered => 1 }参数,让CBOR::XS创建有序哈希 - 关闭Data::Dumper的键排序功能,确保按有序哈希的原始顺序输出
修改后的完整代码
use CBOR::XS; use Tie::IxHash; my $hex_data = "84AA1A300000031901001A10000002031A1000000A011A700001F7011A600003F11B0000023D19D43C001A600003F0001A800003EE41011A900003EF51300F310D300B0603550403130446616B651A600002BD1B00000189DB1BABD91A2000000142020340A040"; my $data = pack "H*", $hex_data; # 开启ordered选项,创建保留原始顺序的哈希 my $decoded_data = CBOR::XS::decode_cbor($data, { ordered => 1 }); use Data::Dumper; local $Data::Dumper::Useqq = 1; # 关闭Data::Dumper的自动键排序 local $Data::Dumper::Sortkeys = 0; print Dumper($decoded_data);
原理说明
- Perl原生哈希是无序的,CBOR::XS默认用原生哈希存储解码结果,导致原始顺序丢失
- 开启
ordered => 1后,CBOR::XS会通过Tie::IxHash绑定哈希,强制保留CBOR数据中的键顺序 - 设置
$Data::Dumper::Sortkeys = 0可以避免Data::Dumper自动对哈希键排序,确保输出顺序与CBOR原始字节顺序一致
内容的提问来源于stack exchange,提问作者sasaki
相关产品推荐
相关产品推荐

