Буферы протокола, что в сериализованных данных?

Я новичок в буферах протоколов и очень хочу узнать об этом больше, так что извините за вопрос noob.

Что находится в сериализованных данных, только значения или и ключи и значения? Я думаю, что есть только ценности, и если кто-то хочет десериализовать его, он / она должен иметь схему.

2 ответа

Решение

Это и ключ, и ценность:

Как вы знаете, буферное сообщение протокола представляет собой серию пар ключ-значение. Бинарная версия сообщения просто использует номер поля в качестве ключа - имя и объявленный тип для каждого поля могут быть определены только в конце декодирования путем ссылки на определение типа сообщения (то есть файл.proto). https://developers.google.com/protocol-buffers/docs/encoding

Например, скажем, у вас есть файл прото как:

$  cat my.proto 
message header {
  required uint32 u1 = 1;
  required uint32 u2 = 2;
  optional uint32 u3 = 3 [default=0];
  optional bool   b1 = 4 [default=true];
  optional string s1 = 5;
  optional uint32 u4 = 6;
  optional uint32 u5 = 7;
  optional string s2 = 9;
  optional string s3   = 10; 
  optional uint32 u6 = 8;
}

Извлечь закодированные данные из памяти:

(gdb) x/10xb 0x7fd70db7e964
0x7fd70db7e964: 0x08    0xff    0xff    0x01    0x10    0x08    0x40    0xf7
0x7fd70db7e96c: 0xd4    0x38

Decode:

$ echo 08ffff01100840f7d438 | xxd -r -p | protoc --decode_raw
1: 32767
2: 8
8: 928375

1,2,8 являются ключами

из файла прото выше:

1 => u1, 
2 => u2,
8 => u6

Итак, это становится:

u1: 32767
u2: 8
u6: 928375

Я использовал данные из моего вопроса здесь:

Это немного зависит от того, используете ли вы двоичную форму (которая обычно используется по умолчанию при работе с protobuf) или форму json (да, protobuf включает опцию json, по крайней мере, в некоторых библиотеках - не во всех).

В двоичной форме данные состоят из номеров полей и значений; не имена полей. В качестве примера, если мы используем пример:

optional string name = 1; // remove the "optional" if using proto3 syntax

и назначить значение "Ника" (и сериализовать его), тогда двоичные данные будут включать 1 (в слегка подправленной форме) и в кодировке UTF-8 Nika, но он не будет содержать "имя".

Вам не обязательно иметь схему для ее декодирования, но если вы сделаете это, вам будет намного проще, так как многие части спецификации являются неоднозначными, используя один и тот же "тип провода" (т. Е. Формат кодирования) для несколько типов данных или для нескольких значений одного и того же типа данных (например: вы не можете сказать, является ли целое число со знаком, без знака или "закодировано зигзагом" без схемы (или правильного предположения) и фактического значения что вы можете получить может сильно варьироваться в зависимости от этого.

Чтобы увидеть, что вы можете получить из необработанных данных protobuf без схемы, попробуйте: https://protogen.marcgravell.com/decode

Другие вопросы по тегам