protobuf编码

 

proto2

Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构化数据序列化,适合做数据存储或 RPC 数据交换格式。可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。

字段规则

  • required: 字段必须存在
  • optional: 字段没有或有一个
  • repeated: 字段重复,0个或多个

proto 数据类型

 

.proto Type
Notes
C++ Type
Java Type
Python Type[2]
Go Type
double固定8字节长度doubledoublefloat*float64
float固定4字节长度floatfloatfloat*float32
int32可变长度编码。对负数编码低效,如果字段可能是负数,用sint32代替int32intint*int32
int64可变长度编码。对负数编码低效,如果字段可能是负数,用sint64代替int64longint/long[3]*int64
uint32可变长度编码,无符号整数uint32int[1]int/long[3]*uint32
uint64可变长度编码,无符号整数uint64long[1]int/long[3]*uint64
sint32可变长度编码。有符号整数。 These more efficiently encode negative numbers than regular int32s.int32intint*int32
sint64可变长度编码。有符号整数。These more efficiently encode negative numbers than regular int64s.int64longint/long[3]*int64
fixed32固定4字节长度,无符号整数。 More efficient than uint32 if values are often greater than 228.uint32int[1]int/long[3]*uint32
fixed64固定8字节长度,无符号整数。 More efficient than uint64 if values are often greater than 256.uint64long[1]int/long[3]*uint64
sfixed32固定4字节长度,有符号整数int32intint*int32
sfixed64固定8字节长度,有符号整数int64longint/long[3]*int64
bool boolbooleanbool*bool
stringUTF-8 encoded or 7-bit ASCII text.stringStringstr/unicode[4]*string
bytes包含任意字节序列stringByteStringstr[]byte

编码规则

1.varints

理解简单protobuf编码,首先要知道varints。varints使用一个字节或多个字节对整数序列化方法。

varints中的每个字节除了最后一个字节,有一个最有效位(most significant bit ,msb),这意味指示之后有其他字节。每个字节的低7位一组数的补码

例如:

1

0000  0001

300

1010  1100  0000  0010

只取每个字节低七位

010  1100  000  0010

小端序->大端序

000  0010  010  1100 -->  0001  0010  1100  =300

 

2.消息结构

protobuf 消息是一系列key-value对,对于二进制消息,字段数字作为关键字。字段的命名和类型在解码时确定。

在进行消息编码时,key/value被连接成字节流。在解码时,解析器可以直接跳过不识别的字段,这样就可以保证新老版本消息定义在新老程序之间的兼容性,从而有效的避免了使用older消息格式的older程序在解析newer程序发来的newer消息时,一旦遇到未知(新添加的)字段时而引发的解析和对象初始化的错误。最后,我们介绍一下字段标号和字段类型是如何进行编码的。每一个 wire-format消息的key实际上是有两个值组成:proto文件中定义的字段标号和wire type。

Type
Meaning
Used For
0Varintint32, int64, uint32, uint64, sint32, sint64, bool, enum
164-bitfixed64, sfixed64, double
2Length-delimitedstring, bytes, embedded messages, packed repeated fields
3Start groupgroups (deprecated)
4End groupgroups (deprecated)
532-bitfixed32, sfixed32, float

key = (field_number << 3) | wire_type key的最后3个bits用于存储字段的类型信息。那么在使用该编码时,Protocol Buffer所支持的字段类型将不会超过8种。

例如:150(十进制) 在protobuf二进制文件中是 08 96 01

08 --> 00001000  field_number=1,wire_type=0

96 01 -> 1001 0110  0000 0001 -->  001 0110   000  0001  -->  000 0001   001  0110   --> 1001  0110 =150

3.Signed Integers

wire_type=0 的类型都以varint 进行编码,所以对于int32和int64,对于负数使用补码,int32 需要5个字节,int64需要10个字节,有符号整数使用ZIgZag编码

ZigZag 将有符号整数映射到无符号整数,以此得到一个绝对值较小的数字(例如-1)j就可以获得一个较小的varint编码值。

 

 

Signed Original
Encoded As
00
-11
12
-23
21474836474294967294
-21474836484294967295

sint32:       (<< 1) ^ (>> 31)

 sint64:       (<< 1) ^ (>> 63)

4.Non-varint Numbers

wire-type=1:fixed64, sfixed64, double 固定64bit

wire-type=5:fixed32, sfixed32, float,固定32bit

5.Strings

wire-type=2,字符串长度使用varint编码

例如

message Test2 {optional string b = 2;
}

b=“testing” ,编码后结果:

12 07 74 65 73 74 69 6e 67

12: field number=2,wire-type=2  (2<< 3)|2=0x12

长度为7 varint编码 0x07

74 65 73 74 69 6e 67  UTF8 编码

6.Embedded Messages嵌套消息

wire-type=2
message Test1 {optional int32 a = 1;
}
message Test3 {optional Test1 c = 3;
}

Test1's a field set to 150

Test3 编码结果: 1a 03 08 96 01

1a: field_number=3,wire_type=2  (3<< 3)|2=11010=0x1a

03: 字节数

08 96 01 : c编码结果

7.Optional And Repeated Elements

proto2 :消息被定义repeated (没有 [packed=true]选项),编码的消息有0或多个使用相同字段标号的key-value对,这些重复的值不必连续出现; 他们可能会与其他字段交错,但在解码时顺序保留

optional字段,编码后的消息可能有也可能没有包含该字段号的键值对。

proto3 使用packed encoding:

包含零个元素的打包重复字段不会出现在编码消息中。这个字段的所有元素都打包到一个wire-type=2的key-value对中

 

message Test4 {repeated int32 d = 4 [packed=true];
}
22        // key (field number 4, wire type 2)
06        // payload size (6 bytes)
03        // first element (varint 3)
8E 02     // second element (varint 270)
9E A7 05  // third element (varint 86942)

proto2默认不设置 packed=true
repeated编码采用空格(0x20)分隔
结果是20 03 20 8e 02 20 9e a7  05

转载于:https://www.cnblogs.com/dj0325/p/9238025.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/280009.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

定制.NET 6.0的Middleware中间件

大家好&#xff0c;我是张飞洪&#xff0c;感谢您的阅读&#xff0c;我会不定期和你分享学习心得&#xff0c;希望我的文章能成为你成长路上的垫脚石&#xff0c;让我们一起精进。在本文中&#xff0c;我们将学习中间件&#xff0c;以及如何使用它进一步定制应用程序。我们将快…

Python-循环控制--个人课堂笔记

Python中的两种循环方式&#xff08;目前学到&#xff09;&#xff1a;for循环和while循环 for循环和while循环的区别&#xff1a; for循环一般用于控制循环的次数&#xff0c;while循环则是条件循环。 操作实例-猜数字小游戏&#xff08;3次猜错提示游戏结束&#xff09;&…

删除microsoft_如何从您的Microsoft帐户中删除设备

删除microsoftWhen you sign into Windows 8 or 10 using your Microsoft account (and other Microsoft devices, like an Xbox), those devices become associated with your account. If you want to remove an old device you’ve gotten rid of, you’ll have to pay a vi…

线程的语法 (event,重要)

Python threading模块 2种调用方式 直接调用 12345678910111213141516171819import threadingimport timedef sayhi(num): #定义每个线程要运行的函数print("running on number:%s" %num)time.sleep(3)if __name__ __main__:t1 threading.Thread(targetsayhi,args(…

求最大值和下标值

本题要求编写程序&#xff0c;找出给定的n个数中的最大值及其对应的最小下标&#xff08;下标从0开始&#xff09;。 输入格式: 输入在第一行中给出一个正整数n&#xff08;1<n≤10&#xff09;。第二行输入n个整数&#xff0c;用空格分开。 输出格式: 在一行中输出最大值及…

windows应用商店修复_如何修复Windows应用商店中的卡死下载

windows应用商店修复Though it’s had its share of flaky behavior since being introduced in Windows 8, the Windows Store has gotten more reliable over time. It still has the occasional problems, though. One of the more irritating issues is when an app update…

OpenWrt:Linux下生成banner

Linux下有三个小工具可以生成banner&#xff1a;1、banner使用#生成banner&#xff1b;2、figlet使用一些普通字符生成banner&#xff1b;3、toilet使用一些复杂的彩色特殊字符生成banner。使用apt-get安装的时候需要输入以下命令&#xff1a; $ sudo apt-get install sysvbann…

新冠病毒中招 | 第二天

今天跟大家分享我个人感染奥密克戎毒株第二天的经历和感受。早上7点多自然醒来&#xff0c;已经没有四肢乏力的感觉&#xff0c;但是身体的本能还是告诉我不愿意动弹。由于第一天躺着睡了一天&#xff0c;确实是躺得腰酸背疼的。起床量了一下体温36.4正常&#xff0c;决定今天不…

输出到Excel

HSSFWorkbook oBook new HSSFWorkbook(); NPOI.SS.UserModel.ISheet oSheet oBook.CreateSheet(); #region 输出到Excel MemoryStream ms new MemoryStream(); oBook.Write(ms);string sExportPath ""; using (SaveFileDialog saveFileDialog1 new SaveFileDial…

JavaScript 精粹 基础 进阶(5)数组

转载请注明出处 原文连接 blog.huanghanlian.com/article/5b6… 数组是值的有序集合。每个值叫做元素&#xff0c;每个元素在数组中都有数字位置编号&#xff0c;也就是索引。JS中的数组是弱类型的&#xff0c;数组中可以含有不同类型的元素。数组元素甚至可以是对象或其它数组…

icloud 购买存储空间_如何释放iCloud存储空间

icloud 购买存储空间Apple offers 5 GB of free iCloud space to everyone, but you’ll run up against that storage limit sooner than you’d think. Device backups, photos, documents, iCloud email, and other bits of data all share that space. Apple为每个人提供5 …

基于LAMP实现web日志管理查看

前言&#xff1a;日志是一个重要的信息库&#xff0c;如何高效便捷的查看系统中的日志信息&#xff0c;是系统管理员管理系统的必备的技术。实现方式&#xff1a;1、将日志存储于数据库。2、采用LAMP架构&#xff0c;搭建PHP应用&#xff0c;通过web服务访问数据库&#xff0c;…

WPF效果第二百零七篇之EditableSlider

前面简单玩耍一下快速黑白灰效果; 今天又玩了一下ZoomBlurEffect,来看看最终实现的效果:1、ps和cs文件都在Shazzam中,咱们自己随意玩耍;今天主角是下面这位:2、来看看自定义控件布局(TextBox、Slider、ToggleButton)&#xff1a;3、点击编辑按钮,我就直接偷懒了:private void E…

闲话高并发的那些神话,看京东架构师如何把它拉下神坛

转载:闲话高并发的那些神话&#xff0c;看京东架构师如何把它拉下神坛 高并发也算是这几年的热门词汇了&#xff0c;尤其在互联网圈&#xff0c;开口不聊个高并发问题&#xff0c;都不好意思出门。高并发有那么邪乎吗&#xff1f;动不动就千万并发、亿级流量&#xff0c;听上去…

c# Clone方法

clone是深拷贝&#xff0c;copy是浅拷贝&#xff0c;如果是值类型的话是没什么区别的&#xff0c;如果是引用类型的话深拷贝拷贝的事整个对象的数据&#xff0c;而浅拷贝仅仅拷贝对象的引用。因为类的实例是引用类型&#xff0c;要想用原有的类中的实例的数据的话&#xff0c;既…

使用MyQ打开车库门时如何接收警报

Chamberlain’s MyQ technology is great for opening and closing your garage door remotely with your smartphone, but you can also receive alerts whenever your garage door opens and closes (as well as receive alerts when it’s been open for an extended amount…

踏实工作,实现价值

工作&#xff0c;为实现自我价值 若想在漫长的职场生涯中稳步高升&#xff0c;首先要踏踏实实&#xff0c;专心致志、充满激情的去完成工作中的每一项任务&#xff0c;无论工作是繁重的还是琐碎的&#xff0c;都要严格要求自己全身心的去完成。而不是一味的抱怨&#xff0c;一味…

mac 防火墙禁止程序联网_如何允许应用程序通过Mac的防火墙进行通信

mac 防火墙禁止程序联网If you use a Mac, chances are you might not even realize that OS X comes with a firewall. This firewall helps ensure unauthorized app and services can’t contact your computer, and prevents intruders from sniffing out your Mac on a ne…

WPF-22 基于MVVM员工管理-02

我们接着上一节&#xff0c;这节我们实现crud操作&#xff0c;我们在EmployeeViewMode类中新增如下成员&#xff0c;并在构造函数中初始化该成员code snippetpublic EmployeeViewMode() {employeeService new EmployeeService();BindData();Employee new Employee();AddComma…

linux 3

-- Linux -- 开心的一天 vi   所有的 unix like 系统都会内置 vi 文本编辑器 vim  较多使用的,可以主动的以字体颜色辨别语法的正确性&#xff0c;方便程序设计 vi/vim 的使用 -- 命令模式&#xff08;Command mode&#xff09; 输入模式&#xff08;Insert mode&#x…