protobuf编码格式解析

2023-05-16

示例

假如定义一个如下的protobuf类型

message Person {
    required string user_name       = 1;
    optional int64  favorite_number = 2;
    repeated string interests       = 3;
}

将其赋值为:

user_name :   "Martin"
favorite_number :    1337
interests:"daydreaming", "hacking"

则生成的数据解析如下:
在这里插入图片描述

数据格式

从上图可以看到整个数据的解析过程。从这个过程中可以看出,实际上。protobuf的数据格式是tag+length+value模式(TLV模式)。如下:
在这里插入图片描述
protobuf数据就是这样一个长条形的序列。再继续细分的话,可以看到tag实际上是有2部分组成。

tag= tag<<3 | type

tag的高5位为tag,tag更容易理解的话就是数据的编号,上例中user_name 的tag=1,说明读到tag=1,后面跟的数据就是user_name。 favorite_number 和interests 都是同理,只不过其编号分别是2 和3,这个tag在定义.proto文件时就会固定。解析的话,就是根据这个tag来表明tag后面的数据含义。

继续看下type是干啥。在protobuf中,谷歌定义了几种数据类,type实际上是一个数据类型的集合。

IDNameUsed For
0VARINTint32, int64, uint32, uint64, sint32, sint64, bool, enum
1I64fixed64, sfixed64, double
2LENstring, bytes, embedded messages, packed repeated fields
3SGROUPgroup start (deprecated)
4EGROUPgroup end (deprecated)
5I32fixed32, sfixed32, float

其中3和4已经废弃掉了实际上没有用到。
示例中第一个字节是0x0a,对应的tag=1,type=2。当type=2的时候,tag后面跟的数据就是length。当type为其他值的时候,tag后面的数据就是value。

解析tag=1数据

继续来看tag=1的数据,
0a 06 4d 61 72 74 69 6e
第二个字节就是长度为6字节,表示tag=1的数据有6字节长度。其value=4d 61 72 74 69 6e ,转换成ascII就是Martin。至此tag=1的数据解析完毕。

解析tag=2数据

继续来看tag=2的数据
10 b9 0a
0x10解析出来后tag=2 ,type=0。此时b9就是数据而不是数据长度。一直tag=2是favorite_number 数据,为1337,所以b9 0a 解析出来应该是1337(0x539)。而1337的十六进制表示0x539,可见这个编码并不是实际的16进制数。

对于数字类型的,采用的是Varints编码模式。这种编码模式采用的是小端模式。其每个字节实际上是拆分成了2个部分。
最高bit(bit7)表面下一个字节是否是数据的一部分。
bit7=1,下一个字节数据中还是包含的数据。
bit7=0,数据只有一个字节
bit6-0 是数据。

具体来看b9 0a这两个数据
b9二进制为1 0111001 ,其bit7=1说明下一个字节0a也是也是favorite_number 的一部分
0a二进制为0 0001010 ,其中bit7=0,说明favorite_number 的数据到此结束。
由于采用的是小端模式。所以最终的数据是0001010 0111001,对应的16进制是539,十进制为1337,这样就解析出来了favorite_number 的值。编码的过程就是这个逆过程。

参考:
https://www.jianshu.com/p/73c9ed3a4877
https://protobuf.dev/programming-guides/encoding/
https://gitee.com/ljango/ddia/blob/master/ch4.md#thrift%E4%B8%8Eprotocol-buffers

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

protobuf编码格式解析 的相关文章

  • 大数据017——Scala基础

    Scala 是一门以 java 虚拟机 xff08 JVM xff09 为目标运行环境并将面向对象和函数式编程语言的最佳特性结合在一起的编程语言 你可以使用Scala 编写出更加精简的程序 xff0c 同时充分利用并发的威力 由于scala
  • 大数据017——Scala进阶

    Scala 基础语法 第二阶段 1 类和对象 1 1 类 1 xff09 简单类和无参方法 如下定义Scala类最简单形式 xff1a class Counter private var value 61 0 必须初始换字段 def inc
  • 大数据018——Spark(一)

    1 Spark 数据分析简介 1 1 Spark 是什么 Spark 是一个用来实现快速而通用的集群计算的平台 在速度方面 xff0c Spark 扩展了广泛使用的 MapReduce 计算模型 xff0c 而且高效地支持更多计算模式 xf
  • ROS 订阅RealsenseD435图像与opencv保存32位深度图像

    一 xff0c 通过ros订阅realsense图像 int main int argc char argv ros init argc argv 34 image listener 34 ros NodeHandle nh cv name
  • 测试左移和右移:不是左右逢源而是左右突击

    持续测试是在软件交付生命周期过程中 xff0c 以防控业务风险为目的 xff0c 将每一个业务交付阶段都辅以测试活动进行质量保障 xff0c 并尽最大可能自动化 xff0c 通过测试结果不断的反馈给制品过程的测试实践活动 随着持续测试实践的
  • 虚拟机ubuntu上安装make和cmake

    可先更新下apt xff1a sudo apt get update 首先安装make xff1a sudo apt get install ubuntu make sudo apt get install make sudo apt ge
  • ros学习笔记(十):树莓派 Ubuntu mate 16.04 开启vncserver 远程桌面+自启动+分辨率修改

    树莓派 Ubuntu mate 16 04 开启vncserver 远程桌面 43 自启动 43 分辨率修改 一 环境 1 树莓派3b 43 Ubuntu 16 04 mate 2 我是在win10 安装的 vncview 软件进行远程桌面
  • 梯度、散度、旋度的关系

    转自 百度文库https wenku baidu com view 681228626137ee06eff918c4 html 知乎上一篇不错的文章 https www zhihu com question 24591127 麦克斯韦方程组
  • 【瓣芽·Banya】React Native 构建的仿豆瓣应用

    今天介绍一个用 React Native 创建的应用 xff0c 集合了豆瓣电影 xff0c 图书等信息展示功能的 app github 地址 瓣芽 Banya 项目使用了react navigation 做路由 redux 做部分状态管理
  • CSS - position

    在 CSS 中 xff0c position 是实现元素定位的一种重要方式 使用定位的元素层叠级别比浮动会更高 xff0c 采用定位来控制元素位置会更加容易 一般我们使用定位 xff0c 是通过使用定位模式和边偏移量来确定元素位置的 定位模
  • React Native 选择器组件 / react-native-slidepicker

    react native slidepicker 一个纯 JavaScript 实现的的 React Native 组件 xff0c 用于如地址 xff0c 时间等分类数据选择的场景 github https github com lexg
  • 函数式组件 ref 的解决方案

    对于 React 中需要强制修改子组件的情况 xff0c React 提供了 Refs 这种解决办法 xff0c 使得我们可以操作底层 DOM 元素或者自定的 class 组件实例 除此之外 xff0c 文档 xff08 v17 0 1 x
  • JavaScript生成指定范围的随机数和随机数序列

    在JavaScript中我们经常使用Math random 方法生成随机数 xff0c 但是该方法生成的随机数只是0 1之间的随机数 先看如下常用方法的特征 xff1a 1 Math random 结果为0 1间的一个随机数 包括0 不包括
  • JavaScript生成指定范围随机数和随机序列

    在JavaScript中我们经常使用Math random 方法生成随机数 xff0c 但是该方法生成的随机数只是0 1之间的随机数 先看如下常用方法的特征 1 Math random 结果为0 1间的一个随机数 包括0 不包括1 2 Ma
  • 【React Native】JavaScript 中 bind 方法

    这个问题其实是一个 JavaScript 中的问题 JavaScript中jQury的bind方法为选定元素添加事件处理程序 xff0c 规定事件发生时运行的函数 语法为 xff1a selector bind event data fun
  • 分层自动化测试模型深入研究

    分层自动化测试模型的发展 分层自动化测试模型最早是由Mike Cohn在2009年出版的 Succeeding with Agile 书中的第十六章进行阐述的 他说 测试金字塔是分层测试的一种最佳实践 金字塔自动化测试模型如上图A所示 从下
  • N个数中的第k个最大值

    确定一组N个数中的第k个最大值 xff0c 这是数据结构和算法分析 java语言描述 中讨论的第一个问题 书中第一章也已给处两种常规思路 xff1a 1 xff0d 先将N个数的数组整体进行递减排序 xff0c 然后返回位置k 数组索引为k
  • 【React Native】app\build\intermediates\res\merged\debug\values-v24\values-v24.xml中错误

    昨天在项目中使用了 react native svg 库 xff0c 配置完成正在正常启动的时候 xff0c 却出现四个错误 xff0c 全部来源于app build intermediates res merged debug value
  • 【React Native】定位获取经纬度,当前城市等地址信息

    2019 8 21 使用内置对象 navigator 来获取经纬度信息 xff0c 参见 定位获取经纬度 xff0c 获取到经纬度等位置信息后需要用到第三方api位置解析 xff08 本文后半段 xff09 2019 7 20更新 xff1
  • 【React Native】定位获取经纬度

    RN 文档上的定位功能需要谷歌框架支持 xff0c 无疑带来了一些麻烦 github 上也有一些开源库 xff0c react native geolocation service等 但是这里还有一个更简便的位置获取 API 使用内置对象n

随机推荐