0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Google二进制编解码技术之Protobuf 3

jf_78858299 来源:码农的荒岛求生 作者:陆小风 2023-02-15 14:29 次阅读
字段名称与字段类型

对于任何一个有用的信息都包含这样几部分:

  • 字段名称
  • 字段类型
  • 字段值

就像C/C++中定义变量时:

int i = 100;

在这里,字段名称就是i,字段类型是int,字段值是100。

刚才我们用varint以及ZigZag编码解决了字段值表示的问题,那么该怎样表示字段名称和字段类型呢?

首先,对于字段类型还比较简单,因为字段类型就那么多,protobuf中定义了6种字段类型:

图片

对于6种字段类型我们使用3个比特位来表示就足够了。

接下来比较有趣的是字段名称该怎么表示呢?假设我们需要传递这样一个字段:

int long_long_name = 100;

那么我们真的需要把“long_long_name”这么多字符通过网络传递给对端吗?

既然通信双方需要协议,那么“long_long_name”这字段其实是client和server都知道的,它们唯一不知道的就是“ 哪些值属于哪些字段 ”。

为解决这个问题, 我们给每个字段都进行编号 ,比如通信双方都知道“long_long_name”这个字段的编号是2,那么对于:

int long_long_name = 100;

这个信息我们只需要传递:

  • 字段名称:2 (2对应字段“long_long_name”)
  • 字段类型:0 (0表示varint类型,参见上图)
  • 字段值:100

所以我们可以看到, 无论你用多么复杂的字段名称也不会影响编码后占据的空间,字段名称根本就不会出现在编码后的信息中, so clever。

从宏观上看

我们已经在protobuf中看到了数字以及字段名称以及字段类型是怎么表示了,现在是时候从宏观角度来看看多个字段该怎么编码了。

从本质上讲,protobuf被编码后形成一系列的key-value,每个key-value对应一个proto中的字段。

也就是键值对:

图片

其中value比较简单,也就是字段值;而字段名称和字段类型会被拼接成key,protobuf中共有6种类型,因此只需要3个比特位即可;字段名称只需要存储对应的编号,这样可以就可以这样编码:

(字段编号 << 3) | 字段类型

假设server接收到了一个key为0x08,其二进制的表示为:

0000 1000

由于key也是利用varint编码的,因此需要将第一个比特位去掉,这样我的得到:

000 1000

根据key的编码方式,其后三个比特位表示字段类型,即:

000

也就是0,这样我们知道该key的类型是Varint(第0号类型),而字段编号为抹掉后3个比特位的值,即:

0001

这样,我们就知道了该key对应的字段编号为1,得到编号我们就能根据编号找到对应的编号名称。

嵌套数据

与Json和XML类似,protobuf中也支持嵌套消息,就像这样:

message SubMsg {
  optional int32 id = 1;
}
message Msg {
  optional SubMsg msg = 1;
}

其实现也比较简单,这依然遵循被编码后形成一系列的key-value,只不过对于嵌套类型的key来说,其value是由子消息的key-value组成。

图片

protobuf与编译语言

与Json一样,protobuf也是一门语言,兼具了文本的可读性以及二进制的高效。

protobuf之所以能做到这一点就好比C语言与机器指令。

C语言是给程序员看的,可读性好,而机器指令是给硬件使用的,性能好,编译器会将C语言程序转为机器可执行的机器指令。

而protobuf也一样,protobuf也是一门语言,会将可读性较好的消息编码为二进制从而可以在网络中进行传播,而对端也可以将其解码回来。

在这里protobuf中定义的消息就好比C语言,编码后的二进制消息就好比机器指令。

而protobuf作为事实上语言必然有自己的语法,其语法就是这样:

图片

怎么样,还觉得编译原理没什么用吗?

不理解编译原理是不可能发明protobuf这种技术的。

总结

我在写这篇文章时不断感叹,Google的这项技术节省了多少程序员的时间,同时我们也能看到这种基石般的技术依赖的底层原理却非常古老:

  • 信息的编解码
  • 编译原理

怎么样,这些是不是远远没有IT界各种流行的技术听上去时髦有趣,而正是这种朴素的技术支撑起了工业界,现在你也应该能明白底层技术的重要性了吧。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 计算机
    +关注

    关注

    19

    文章

    6653

    浏览量

    84617
  • Server
    +关注

    关注

    0

    文章

    88

    浏览量

    23857
  • 网络编程
    +关注

    关注

    0

    文章

    64

    浏览量

    9982
收藏 人收藏

    评论

    相关推荐

    探讨2对4二进制解码器及4到16二进制解码器配置

    二进制解码器是由单独的逻辑门构成的另一种组合逻辑电路,与编码器完全相反。名称“解码器”是指将编码信息从一种格式转换或解码为另一种格式,因此二进制
    的头像 发表于 12-29 12:10 8772次阅读
    探讨2对4<b class='flag-5'>二进制</b><b class='flag-5'>解码</b>器及4到16<b class='flag-5'>二进制</b><b class='flag-5'>解码</b>器配置

    二进制码详解

    本帖最后由 gk320830 于 2015-3-9 06:39 编辑 二进制码  数字系统中的信息可分为两类,一类是数值,另一类是文字符号(包括控制符)。  代码:采用一定位数的二进制数码来
    发表于 04-06 23:55

    二进制格雷码与自然二进制码的互换

    。而绝对式编码器是直接输出数字量的传感器,它是利用自然二进制或循环二进制(格雷码)方式进行光电转换的,编码的设计一般是采用自然二进制码、循环二进制码、
    发表于 03-08 14:16

    基于FPGS二进制LDPC

    一个8位二进制数经过二进制LDPC编码器编码后等到一个几位二进制的数,怎么计算的?
    发表于 03-14 13:07

    Labview图像二进制转换问题

    `各位大神,我想把一张图片通过变成二进制通过TCP传输,现在我把图片转换成二进制文件,但文件只有1KB大小。我想读取但是不知道二进制的图片数据类型。能否帮我画一个简易的读取二进制图片的
    发表于 12-29 09:26

    如何理解二进制运算规则 二进制是如何运算的

    (11100101.11101011)2转换成八进制数。 (11100101.11101011)2=(345.353)8(3二进制转换为十六进制:采用的是“四位一并法”,整数部分从低
    发表于 12-11 17:49

    如何丢弃函数的二进制代码填入SRAM的二进制代码?

    应用程序 : 示例代码演示了如何丢弃函数的二进制代码, 然后填入 SRAM 的二进制代码, 然后调用它 。 BSP版本:M451系列BSP V3.01.001 硬件: 任何 M451 系列板块
    发表于 08-23 06:34

    二进制

    二进制   二进制与十进制的区别在于数码的个数和进位规律有很大的区别,顾名思义,二进制的计数规律为逢二进一,是以2为基数的计数体制。10这
    发表于 04-06 23:48 7678次阅读
    <b class='flag-5'>二进制</b>

    二进制编码和二进制数据

    二进制编码和二进制数据   二进制编码是计算机内使用最多的码制,它只使用两个基本符号"0"和"1",并且通过由这两个符号组成的
    发表于 10-13 16:22 4524次阅读

    二进制电平,什么是二进制电平

    二进制电平,什么是二进制电平 在二进制数字通信系统中,每个码元或每个符号只能是“1”和“0”两个状态之一。若将每个码元可能取的状态增
    发表于 03-17 16:51 2272次阅读

    二进制解码器案例说明

    二进制解码器是另一种由各个逻辑门构成的组合逻辑电路,与编码器完全相反。
    的头像 发表于 06-22 09:41 8647次阅读
    <b class='flag-5'>二进制</b><b class='flag-5'>解码</b>器案例说明

    二进制解码器到底是什么

    二进制解码器是由单独的逻辑门构成的另一种组合逻辑电路,与编码器完全相反。名称“解码器”是指将编码信息从一种格式转换或解码为另一种格式,因此二进制
    发表于 01-03 17:42 5785次阅读
    <b class='flag-5'>二进制</b><b class='flag-5'>解码</b>器到底是什么

    Google二进制编解码技术Protobuf 1

    计算机网络编程中一个非常基本的问题:该怎样表示client与server之间交互的数据,在往下看之前先想一想这个问题。 ##### **共识与协议** 这个问题可不像看上去的那样简单,因为client进程和server进程运行在不同的机器上,这些机器可能运行在不同的处理器平台、可能运行在不同的操作系统、可能是由不同的编程语言编写的,server要怎样才能识别出client发送的是什么数据呢?就像这样
    的头像 发表于 02-15 14:28 294次阅读
    <b class='flag-5'>Google</b><b class='flag-5'>二进制</b><b class='flag-5'>编解码</b><b class='flag-5'>技术</b>之<b class='flag-5'>Protobuf</b> 1

    Google二进制编解码技术Protobuf 2

    计算机网络编程中一个非常基本的问题:该怎样表示client与server之间交互的数据,在往下看之前先想一想这个问题。 ##### **共识与协议** 这个问题可不像看上去的那样简单,因为client进程和server进程运行在不同的机器上,这些机器可能运行在不同的处理器平台、可能运行在不同的操作系统、可能是由不同的编程语言编写的,server要怎样才能识别出client发送的是什么数据呢?就像这样
    的头像 发表于 02-15 14:28 473次阅读
    <b class='flag-5'>Google</b><b class='flag-5'>二进制</b><b class='flag-5'>编解码</b><b class='flag-5'>技术</b>之<b class='flag-5'>Protobuf</b> 2

    二进制解码器开源设计

    电子发烧友网站提供《二进制解码器开源设计.zip》资料免费下载
    发表于 06-16 15:01 0次下载
    <b class='flag-5'>二进制</b><b class='flag-5'>解码</b>器开源设计