如何用Perl及Google::ProtocolBuffers模块获取十六进制格式数据
问题:如何通过Google::ProtocolBuffers模块获取十六进制格式的数据?
我编写了如下Perl测试代码来读取十六进制格式的数据:
#!/usr/bin/perl -w use Google::ProtocolBuffers; use File::Slurp qw(read_file write_file); Google::ProtocolBuffers->parse(" message TestMessage { required double tag1 = 1; } ", {create_accessors => 1 } ); my $enc = TestMessage->encode({ tag1 => 0, }); write_file('data.bin', { binmode => ':raw' } , $enc); my $dec = read_file('data.bin', { binmode => ':raw' }); my $protoc = TestMessage->decode($dec); print $protoc->tag1;
使用Google::ProtocolBuffers模块时,它会将所有数值识别为float64并返回Perl原生数值;而使用protoc命令解析时,结果是十六进制格式,符合预期:
C:\Users\user\Desktop>protoc --decode_raw < data.bin 1: 0x0000000000000000
请问如何通过该模块获取十六进制格式的数据?
解决方案
Google::ProtocolBuffers的decode方法会自动将Protobuf中的double类型转换为Perl的原生数值类型,不会直接返回十六进制格式的字节表示。要得到和protoc --decode_raw一致的十六进制输出,你需要手动将解码后的数值重新打包为二进制,再转换为十六进制字符串:
# 在原代码的print语句后添加以下代码 my $value = $protoc->tag1; # 把Perl数值打包为大端序的double二进制(Protobuf使用大端字节序) my $binary = pack('d>', $value); # 将二进制转换为十六进制字符串 my $hex_str = unpack('H*', $binary); # 输出带0x前缀的十六进制格式 print "\n1: 0x$hex_str\n";
运行修改后的代码,就能得到和protoc命令一致的十六进制输出:
0 1: 0x0000000000000000
原理说明:
pack('d>', $value):将Perl的数值按照大端序打包为64位double类型的二进制数据,和Protobuf编码时的字节序一致。unpack('H*', $binary):将二进制数据转换为十六进制字符串,每个字节对应两位十六进制字符。
内容的提问来源于stack exchange,提问作者glen danzig
相关产品推荐
相关产品推荐

