如何在 Python 中解码 protobuf 时提取和打印正确的值

Posted

技术标签:

【中文标题】如何在 Python 中解码 protobuf 时提取和打印正确的值【英文标题】:How to extract and print the correct value while decoding the protobuf in Python 【发布时间】:2017-05-06 11:42:35 【问题描述】:
(Pdb) p mac
'\xd0\xbf\x9c\xd8\xf0\x00'
p type(mac)
<type 'str'>

使用 Python2.7,如何提取和打印准确的 MAC 地址? 在 .proto 消息中,mac_address 定义为 “可选字节 mac”。

【问题讨论】:

难道没有办法解码并查看内容。为什么人们要进行字符串格式化。这不是我要找的…… 也许你可以展示你想要的结果对于你给定的示例字符串的样子,因为“解码”可能意味着很多不同的东西。 【参考方案1】:
import struct
a='\xd0\xbf\x9c\xd8\xf0\x00'
for i in range(6):
  print hex(struct.unpack("B", a[i])[0])[2:], ":",

打印

d0 : bf : 9c : d8 : f0 : 0 :

【讨论】:

不是这样的。我的意思是我收到的 protobuf 作为一些变量作为字符串和一些 mac.. 当我打印它时,所有在 .proto 中定义为整数的变量,字符串都很好,除了类型是字节的变量。没有更通用的显示方式吗?【参考方案2】:
':'.join([hex(c)[2:] for c in map(ord,'\xd0\xbf\x9c\xd8\xf0\x00')])

打印:

'd0:bf:9c:d8:f0:0'

基本上,这一行将十六进制字符串转换为 0 到 255 范围整数的列表,然后将每个元素 c 转换回不带 '\x' 字符的十六进制字符串,然后将列表元素作为字符串连接':' 介于两者之间。

【讨论】:

你也可以r'\xd0\xbf\x9c\xd8\xf0\x00'.replace(r'\x','',1).replace(r'\x',':')这样更干净 我认为没有直接的类型转换方法。也许您可以使用正则表达式获得更漂亮的结果。【参考方案3】:

这可能吗?

>>> mac_str = ':'.join(":02x".format(ord(c)) for c in mac)
>>> print(mac_str)
d0:bf:9c:d8:f0:00

如果你只想要整数列表:

mac_decoded = [ord(c) for c in mac]

不知道你所说的“解码”是什么意思...

【讨论】:

以上是关于如何在 Python 中解码 protobuf 时提取和打印正确的值的主要内容,如果未能解决你的问题,请参考以下文章

如何解码二进制/原始谷歌 protobuf 数据

Go是如何实现protobuf的编解码的: 源码

Go是如何实现protobuf的编解码的: 原理

Protobuf : WebApi -> JS - 解码对象为空

Netty系列化之Google Protobuf编解码

十一.Netty入门到超神系列-Netty使用Protobuf编码解码