ProtoBuf原理

一、参考文章

https://zhuanlan.zhihu.com/p/404782892

二、测试

1.test.proto

syntax = "proto3";

package proto;
option go_package = "./;proto";

message Msg{
    uint32 age1 = 1;
    sint32 age2 = 2;
    string name = 3;
    bytes data = 4;
}

2.main.go

package main

import (
	"fmt"
	pb "test/proto"

	"google.golang.org/protobuf/proto"
)

func main() {

	{
		m := pb.Msg{Age1: 5, Age2: -5, Name: "aaa", Data: []byte("111我")}

		d, err := proto.Marshal(&m)
		if err != nil {
			return
		}
		fmt.Println(fmt.Sprintf("%08b", d))
	}

	fmt.Printf("%08b\n", []byte("我"))
}

3.结果:

 4.分析:

由于protobuf编码后由 key-value组成

则:

age1为  00001000 00000101

其中:

00001000 = 1 << 3 | 0,

00000101 就是5的varint编码;

age2为  00010000 00001001

其中:

00010000 = 2 << 3 | 0

00001001 是-5经过zigzag编码->varint编码的结果

name为 00011010 00000010 01100001 01100001

其中:

00011010 = 3 << 3 | 2

00000010代表长度2

01100001就是字符a的AISCII编码97

data为 00100010 00000101 00110001 00110001 11100110 10001000 10010001

其中:

00100010 = 4 << 3 | 2

00000101代表长度5

01100001就是字符a的AISCII编码97

11100110 10001000 10010001 就是‘我’。

由fmt.Printf("%08b\n", []byte("我"))可以得到‘我’的二进制编码。

得出以下结论:

1.protobuf不会对string,bytes进行压缩,按照内存中的格式进行传输。

2.protobuf会对数字进行压缩传输,注意使用负数时,应使用sint32、sint64。

3.protobuf不像json,xml一样传输字段,而是传输字段在结构中的序号。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值