FreeToGenerate.com

Pega bytes de protobuf y mira todas las lecturas que permite el formato, en vez de una suposición presentada como respuesta. No se sube nada.

Hex o base64. Se ignoran los espacios, los dos puntos y los prefijos 0x.

Prueba con uno

Todas las lecturas válidas

6 bytes · 3 campos · 3 ambiguos

Campo 1tipo 2 · delimitado por longitud
como campo repetido empaquetado8, 42, 16, 7
como bytes082a1007

como mensaje anidadodentro

Campo 1tipo 0 · varint
como int32, int64, uint32, uint64 o enum42
como sint32 o sint64 (zigzag)21
Campo 2tipo 0 · varint
como int32, int64, uint32, uint64 o enum7
como sint32 o sint64 (zigzag)-4

Cuando un campo tiene más de una lectura, todas son correctas. El formato binario no guarda cuál se quiso decir: eso solo lo dice un archivo .proto. Así que cualquier herramienta que aquí te enseñe una única respuesta ha adivinado.

También disponible en: English · Português · Français · العربية

Decodificador de protobuf

Decodifica bytes de Protocol Buffers sin el archivo .proto y comprueba exactamente qué partes del mensaje se pueden recuperar y cuáles no.

Qué se puede recuperar y qué no

Protocol Buffers codifica un mensaje como una secuencia de campos, cada uno con una cabecera pequeña y una carga útil. La cabecera es un solo varint que lleva el número de campo y un tipo de tres bits, y toda carga útil o se autodelimita o va precedida de su longitud. Con eso basta para recorrer el mensaje entero sin saber nada de él, y por eso decodificar protobuf sin el archivo .proto funciona.

Y eso es también todo lo que hay. Los nombres de los campos no viajan en el binario de ninguna forma, así que un decodificador puede decirte que el campo 3 vale 1500, pero nunca que ese campo se llama timeout_ms. No es una limitación de esta herramienta: los nombres sencillamente no están, y no hay ingenio que los recupere.

Más allá de eso hay dos cosas que son de verdad indecidibles, y son la razón de que esta página muestre varias lecturas por campo. Un varint es a la vez un int32, un int64, un uint32, un uint64, un bool y un enum válidos, y como sint32 y sint64 usan codificación zigzag, el número en sí cambia: el varint 3 es 3 como uint y −2 como sint. A la vez, un campo delimitado por longitud puede ser una cadena, bytes en bruto, un mensaje anidado o un campo repetido empaquetado, y nada en la codificación los distingue.

Cómo se usa

  1. Pega los bytes. Hex o base64, con espacios o sin ellos, con dos puntos o con prefijos 0x. Los bytes copiados tal cual de una captura de red o de una línea de log valen así.
  2. Recorre la lista de campos. Cada campo muestra su número, su tipo y todas las interpretaciones que permite la codificación. Los mensajes anidados se despliegan ahí mismo.
  3. Trata varias lecturas como ambigüedad real. Cuando un campo tiene más de una, todas son correctas y el formato no registra cuál se quiso decir. El contador de arriba dice cuántos campos están en esa situación.

El ejemplo por el que empezar

Los bytes 0a 04 08 2a 10 07 son los que vienen por defecto en el cuadro de arriba. Se leen como el campo 1 con una carga útil de cuatro bytes, y esa carga es a la vez un mensaje anidado perfectamente válido con el campo 1 a 42 y el campo 2 a 7, y un bloque opaco de cuatro bytes igual de válido. Las dos lecturas valen. Nada en esos seis bytes dice cuál quiso decir quien los envió.

No es un caso rebuscado: es la situación normal de cualquier campo delimitado por longitud, y por eso un decodificador que imprime una sola respuesta te está enseñando su propia suposición. Una cadena binaria corta se interpretará como mensaje por casualidad más a menudo de lo que parece, y un mensaje anidado siempre se puede leer además como bytes. Lo único que resuelve esto es el esquema, y si tuvieras el esquema no estarías aquí.

Hay una cosa que el formato sí te dice a gritos. Los tipos 3 y 4 eran las antiguas marcas de inicio y fin de grupo, abandonadas hace muchos años, y el 6 y el 7 nunca se han asignado. Si los bytes contienen alguno, o son muy antiguos o no son protobuf, y esta página lo dice en vez de producir un sinsentido verosímil.

Límites honestos y cómo se ha comprobado

Esto decodifica el formato binario y nada por encima de él. No te dirá el tipo del mensaje, no resuelve nombres de campo y no intenta adivinar un esquema a partir de los números. Tampoco decodifica los tipos envoltorio conocidos ni Any, porque ambos necesitan los descriptores para significar algo.

Cuando una carga útil puede ser varias cosas, la lectura como mensaje anidado va primero si encaja, porque en tráfico real suele ser eso. Ese orden es una comodidad y explícitamente no un veredicto: las lecturas como cadena y como bytes se muestran siempre junto a ella, y las cargas con caracteres de control no se ofrecen como texto aunque sean UTF-8 válido, porque una cadena llena de caracteres no imprimibles es ruido disfrazado de información.

La implementación está anclada a los ejemplos que la propia documentación del formato publica, en vez de a expectativas inventadas aquí: el campo 1 como varint 150 es 08 96 01, el campo 2 como la cadena testing, el ejemplo empaquetado con 3, 270 y 86942, y la tabla zigzag publicada. El conjunto de pruebas ejecuta 577 comprobaciones con 17 controles negativos. Pasó a la primera, que es justo cuando menos hay que fiarse de unas pruebas, y romper el motor a propósito encontró entonces tres huecos reales: ninguna prueba comprobaba un valor de ancho fijo, así que leerlos al revés pasaba desapercibido; nada quedaba a caballo del umbral de reinterpretación con signo; y ninguna carga era a la vez UTF-8 válido y caracteres de control, que es la única forma de ejercitar la comprobación de texto.

¿Por qué es gratis?

Esto es análisis de bytes y funciona en la pestaña que ya tienes abierta. Ningún servidor ve tus bytes, así que no hay nada que facturar ni cuenta que crear.

Nada de lo que pegues se sube, se guarda ni se registra. Las tramas de protobuf capturadas suelen contener identificadores, tokens y datos personales, así que conviene decirlo claramente en vez de dejar que lo supongas.