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

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

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


person Nika Kurashvili    schedule 06.12.2018    source источник


Ответы (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

Расшифровать:

$ 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

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

person brokenfoot    schedule 06.12.2018
comment
исключительно для удобства — это может быть полезным инструментом наряду с протоколом (особенно если вы отлаживаете, так как он объясняет каждый байт): protogen.marcgravell.com/decode?hex=08FFFF01100840F7D438 - person Marc Gravell; 06.12.2018

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

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

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

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

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

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

person Marc Gravell    schedule 06.12.2018