首页 > 其他分享 >protobuf学习

protobuf学习

时间:2023-06-17 15:57:41浏览次数:54  
标签:protobuf proto int float long 学习 Integer string

下载Protobuf

下载地址:https://github.com/protocolbuffers/protobuf/releases

Python安装Protobuf

在python中使用protobuf,还需要安装python对应的protobuf包(否则会报错:No module named goofgle):

pip install protobuf==3.12.0

proto文件语法

message Person{
	required string name = 1;
    message Info{
    	required int32 id = 1;
        repeated string phonenumber = 2;
	}
    repeated Info info = 2;
}

此外,从上面proto文件中也可以发现,message中不同属性可以有不同的限定修饰符,有3种:

  • required:发送方发送的数据中必须包含这个字段的值,接收方接收的数据也必须要能识别该字段,大白话,加上required修饰符,这个字段双方必须使用,否则报错。

  • optional:可选字段,发送方可选择性地发送该字段,接收方如果能够识别该字段就进行相应解码处理,如果不能识别,则直接忽略。

  • repeated:可重复字段,发送方每次发送都可以包含多个值,类似于传递一个数组。

在日常使用protobuf时,有两个常见的tips:

1.分配标识号一般会按业务划分,不同业务间字段不按大小顺序紧密排序,如:

message data {
	optional string name = 10001;
	optional int32 age = 10002;
	optional string job = 20001;
	optional string hobby = 20002;
}

上述proto,基础信息(name、age)以1000开头,其他信息(job、hobby)以2000开头,这样后续要添加时,更加清晰,比如要添加性别这个基本信息 :optional string sex = 10003;。

.proto type notes C ++ type Java type Python type [2] Type Ruby type C# type PHP type
double
double double float float64 float double float
float
float float float FLOAT32 float float float
INT32 使用可变长度编码。编码负数的效率低 - 如果您的字段可能有负值,请改用sint32。 INT32 INT INT INT32 Fixnum or Bignum (as needed) INT Integer
Int64 使用可变长度编码。编码负数的效率低 - 如果您的字段可能有负值,请改用sint64。 Int64 long int / long [3] Int64 TWINS long Integer/string[5]
UINT32 使用可变长度编码。 UINT32 int [1] int / long [3] UINT32 Fixnum or Bignum (as needed) UINT Integer
UINT64 使用可变长度编码。 UINT64 Long [1] int / long [3] UINT64 TWINS ULONG Integer/string[5]
SINT32 使用可变长度编码。签名的int值。这些比常规int32更有效地编码负数。 INT32 INT INT INT32 Fixnum or Bignum (as needed) INT Integer
sint64 使用可变长度编码。签名的int值。这些比常规int64更有效地编码负数。 Int64 long int / long [3] Int64 TWINS long Integer/string[5]
fixed32 总是四个字节。如果值通常大于2 28,则比uint32更有效。 UINT32 int [1] int / long [3] UINT32 Fixnum or Bignum (as needed) UINT Integer
fixed64 总是八个字节。如果值通常大于2 56,则比uint64更有效。 UINT64 Long [1] int / long [3] UINT64 TWINS ULONG Integer/string[5]
sfixed32 总是四个字节。 INT32 INT INT INT32 Fixnum or Bignum (as needed) INT Integer
sfixed64 总是八个字节。 Int64 long int / long [3] Int64 TWINS long Integer/string[5]
Boolean
Boolean Boolean Boolean Boolean TrueClass / FalseClass Boolean Boolean
string 字符串必须始终包含UTF-8编码或7位ASCII文本。 string string str / unicode[4] string String (UTF-8) string string
byte 可以包含任意字节序列。 string Byte string Strait []byte String (ASCII-8BIT) Byte string string

编译proto文件

& "C:\Users\admin\Downloads\protoc-21.1-win64\bin\protoc.exe" --python_out=. demo.proto

在Python中的基本使用

我们定义一个简单的proto文件,名为demo.proto,内容如下:

syntax = "proto3";

message Person {
    string name = 1;
    int32 age = 2;
}

通过protoc将demo.proto编译成Python文件,命令如下(protoc路径替换成自己的路径则可):

& "C:\Users\admin\Downloads\protoc-21.1-win64\bin\protoc.exe" --python_out=. demo.proto

--python_out用于指定生成Python文件要存放的路径,随后紧接demo.proto文件路径(注意有空格做间隔)。

运行命令后,会生成名为demo_pd2.py的文件。

然后我们导入demo_pd2文件,使用其中的Person类便可以实现Protobuf的编码与解码。

通过一段简单的代码演示一下:

# 导入proto
from demo_pb2 import Person

# 构造消息实体
p = Person()
p.name = "zhu"
p.age = 20
# 将实体转换成二进制
sp = p.SerializeToString()
print(sp)
# 构造消息实体
p2 = Person()
# 将二进制数据转换成实体
p2.ParseFromString(sp)
print(p2)

上述代码中,需要注意的是,ParseFromString函数不会直接返回解析后的结果,而是将结果直接填充到调用它的parse_person对象中。

blackboxprotobuf

blackboxprotobuf可以不用提前编写proto文件来解码出proto的结构

https://github.com/nccgroup/blackboxprotobuf

pip install blackboxprotobuf

复制十六进制到代码中

import blackboxprotobuf,base64 

print(blackboxprotobuf.decode_message(base64.b64decode('base64内容')))

在线工具:https://gchq.github.io/CyberChef/

标签:protobuf,proto,int,float,long,学习,Integer,string
From: https://www.cnblogs.com/pigke/p/17487556.html

相关文章

  • Django学习笔记
    1.常用命令创建项目:django-adminstartproject项目名创建APP(进入工程目录):pythonmanage.pystartapp网站名创建库表(进入工程目录):pythonmanage.pymakemigrations执行库表建立(进入工程目录):pythonmanage.pymigrate启动运动:pythonmanage.pyrunserver模板渲染嵌入......
  • 【深入浅出Docker原理及实战】「原理实战体系」零基础+全方位带你学习探索Docker容器
    专栏简介本专栏将带领您进入Docker的世界。您是否对Docker有所耳闻?那么,您是否知道使用Docker可以带来什么样的好处呢?如果您还不了解Docker,不用担心,让我们一起探索这个神奇的世界吧!DockerDocker最初是dotCloud公司内部项目,由SolomonHykes在法国创立。它基于dotCloud公司多年......
  • Day04学习日志
    Day04学习日志Scanner之前我们学的基本语法中我们并没有实现程序和人的交互,但是Java给我们提供了这样一个工具类,我们可以获取用户的输入。java.util.Scanner是Java5的新特征,我们可以通过Scanner类来获取用户的输入。基本语法:Scanners=newScanner(System.in);通过Sc......
  • 学习《操作系统导论》07
    分段根据前面介绍到的基址+界限寄存器对的方式,虽然很好的解决了地址转换的问题,但是可以看到,它也带来了一个问题:内存浪费。根据前面介绍到的那种内存分配处理方式,堆和栈之间会有大量的空闲空间,而前面的介绍中,这些空间都会被一次性装入内存中,那在程序运行的初期,就会有大量没有被使......
  • 2023 年要学习的 10 大 DevOps 技能
    2023年要学习的10大DevOps技能DevOps是两个不同领域的混合体,即开发和运维。这提高了更快地发布软件应用程序的能力,与传统软件开发方法相比,具有快节奏的改进和演变。它使团队能够更快地根据市场进行创新和适应,促进版本的增加,这有助于轻松识别和修复错误,并在改进团队间协作的帮......
  • 万能欧几里得 学习笔记
    题目先放板子:求\(\sum\limits_{x=1}^{L}{A^xB^{\lfloor\frac{Px+R}{Q}\rfloor}}\),其中\(L,P,Q,R\leq10^{18}\)现在看来这个问题比较棘手,不过我们可以先从一些简单的东西入手。思想考虑这样一条直线\(y=\frac{Px+R}{Q}(0\leqR<Q)\),将它在平面直角坐标系中画出来......
  • Navicat For Redis 的学习与使用
    NavicatForRedis的学习与使用背景周末在家看了几个公众号:说到Navicat16.2已经有了Redis的客户端.想着前段时间一直在学习Redis,但是没有GUI的工具,所以想可以试用一下.这里简单总结和记录一下最新版的下载地址#最新版的集合版本premium里面包含多种数据库的连接工具......
  • 疯狂GC的第二种处理方式-ChatGPT的学习之四
    疯狂GC的第二种处理方式-ChatGPT的学习之四摘要上一个脚本太复杂了.而且要改启动脚本.课间休息跟人扯淡聊起来chatGPT发现他的语法很有用但是思路不太对.不过突然根据文档里写的想到了一个新的思路.获取GC信息whiletruedate>>/zhaobsh/gcutiljstat-gcutil`jps|......
  • 斜率优化dp 学习笔记
    斜率优化dp引入首先,我们考虑一种更简单的dp优化——单调队列优化。比如,一个dp式形如:\[dp_{i}=\min_{k\leqj\leqi}(dp_j+f_j+g_i)\]我们发现,这个式子可以通过拆分(wgj:分离变量),变形成如下式子:\[dp_{i}=\min_{k\leqj\leqi}(dp_j+f_j)+g_i\]怎么样?我们发现,取最小......
  • 日语语法学习笔记
    对应课程名词谓语句~だ只能接终助词或句号否定:~ではない疑问:~(か)~です对听话人礼貌否定:~ではありません疑问:~ですか~ですか、~ですか:前升后降~である正式场合对听话人礼貌:~であります~でございます敬语,郑重~は/が格助词は:强调主语が:强调宾语......