protobuf

pb2与pb3

https://stackoverflow.com/questions/56673362/can-proto2-talk-to-proto3
https://stackoverflow.com/questions/42622015/how-to-define-an-optional-field-in-protobuf-3

Encode

protobuf编码算法

Type Meaning Used For
0 Varint int32, int64, uint32, uint64, sint32, sint64, bool, enum
1 64-bit fixed64, sfixed64, double
2 Length-delimited string, bytes, embedded messages, packed repeated fields
3 Start group groups (deprecated)
4 End group groups (deprecated)
5 32-bit fixed32, sfixed32, float

Each key in the streamed message is a varint with the value (field_number << 3) | wire_type – in other words, the last three bits of the number store the wire type.

zigzag算法, 小整数压缩算法

// 以int为例, 先将int转成前导0的整数(最低位表示最高位符号位, 其余31位用符号位异或), 再自低位开始每隔7位进行划分, 最高位表示后续是否还有信息
int int_to_zigzag(int n) {
   return (n <<1) ^ (n >>31);
}
int zigzag_to_int(int n) {
  return (((unsignedint)n) >>1) ^ -(n & 1);
}

int write_to_buffer(int zz, byte* buf, int size) {
   int ret = 0;
   for (int i = 0; i < size; i++) {  
      if ((zz & (~0x7f)) ==0) {
         buf[i] = (byte)zz;
         ret = i + 1;
         break;
      }
      else {
         buf[i] = (byte)((zz & 0x7f) | 0x80);
         zz = ((unsignedint)zz) >> 7;
      }
   }
   return ret;
}

int read_from_buffer(byte* buf, int max_size) {
   int ret = 0;
   int offset = 0;
   for (int i = 0; i < max_size; i++, offset += 7) {
      byte n = buf[i];
      if ((n & 0x80) != 0x80) {
         ret |= (n << offset);
         break;
      }
      else {
         ret |= ((n & 0x7f) << offset);
      }
   }
   return ret;
}
  1. optional字段如果不填会占用空间吗?
    答:不会。

  2. int32、fixed32、sint32有什么区别?uint32和enum在序列化后是否有什么区别?
    答:int32和sint32类似,都是变长存储,适合大多数情况下数值较小的场景,sint32更适合用在负数较多的场景。fixed32是定长存储,适合数值较大的场景(有效位在4字节)。所谓适合,是指序列化后更省空间。
    enum和uint32在序列化后没有区别,反序列化解析时,对于enum会判断有效性,若无效(超出定义范围),则忽略。

  3. 如果有一方把某字段类型从uint32升级成了uint64会怎样?即双方不一致
    答:uint32和uint64在序列化后是同一种类型,即varint(变长整数)。如果是接收方升级成uint64,正常工作;如果发送方升级成uint64,接收方对于超出uint32的值会截断,只保留低32位。

  4. string和bytes有什么区别?
    答:序列化后没有区别;代码实现看,调试版string比bytes多了utf-8的检查,非调试版没有区别。

  5. 生成的字节流是否有压缩?是否有加密?
    答:对于整数类型,有简单压缩,即varint编码。没有加密,纯明文。

  6. 不同版本的protobuf生成的字节流是否有差异?
    答:没有差异。也没有包头字段表示字节流是哪个版本的protobuf生成的。

posted @ 2021-02-27 23:18  我在地狱  阅读(267)  评论(0编辑  收藏  举报