原理¶
Varint 编码¶
Varint 是一种使用一个或多个字节序列化整数的方法,会把整数编码为变长字节。除了最后一个字节外,Varint 编码中的每个字节都设置了最高有效位(most significant bit,msb),msb 为 1 则表明后面的字节还是属于当前数据的,如果是 0 那么这是当前数据的最后一个字节数据。
例:
// 1 用一个字节就可以表示,所以 msb 为 0
0000 0001
// 如果需要多个字节表示,msb 就应该设置为 1 ,例如 300,如果用 Varint 表示的话
1010 1100 0000 0010
Varint 是一种紧凑的表示数字的方法,300 如果用 int32 表示,需要 4 个字节,现在用 Varint 表示,只需要 2 个字节了,缩小了一半。从统计的角度来说,一般不会所有的消息中的数字都是大数,因此大多数情况下,采用 Varint 后,可以用更少的字节数来表示数字信息。
Protobuf 序列化的 string 类型和 byte 类型是直接存储的,只有 int 采用了变长压缩。
Message 结构¶
Protobuf 的 message 是一系列键值对,message 的二进制版本只是使用字段号(field’s number 和 wire_type) 作为 key。每个字段的名称和声明类型只能在解码端通过引用消息类型的定义(即 .proto 文件)来确定,这一点也是人们常常说的 protocol buffer 比 JSON,XML 安全一点的原因,如果没有数据结构描述 .proto 文件,拿到数据以后无法解释成正常的数据。