2010-02-06 10 views
18

Por lo tanto, estoy obteniendo esta información. Desde el conector de red, o desde un archivo. Estoy improvisando un código que interpretará los datos. Lea algunos bytes, revise algunos indicadores y algunos bytes indican la cantidad de datos que sigue. Lee en esa cantidad de datos, enjuaga, repite.Nombreme un analizador binario. Un analizador de datos binarios

Esta tarea me recuerda mucho a analizar el código fuente. Estoy cómodo con lex/yacc y antlr, pero no están a la altura de esta tarea. No puedes especificar bits y bytes crudos como tokens (bueno, tal vez podrías, pero no sabría cómo), y no puedes convertirlos en "leer dos bytes, convertirlos en un entero de 16 bits sin signo, llámalo n, y luego lea n bytes. ".

Por otra parte, cuando la especificación del formato de protocolo/datos se define de manera sistemática (no todos son), debe haber una forma sistemática de leer datos formateados de acuerdo con el protocolo. ¿Derecha?

Tiene que haber una herramienta que lo haga.

Respuesta

7

Usted puede tratar de emplear Boost.Spirit (v2), que ha conseguido recientemente binary parsing tools, endianness-conscientes native y mixedparsers

// This is not a complete and useful example, but just illustration that parsing 
// of raw binary to real data components is possible 
typedef boost::uint8_t byte_t; 
byte_t raw[16] = { 0 }; 
char const* hex = "01010000005839B4C876BEF33F83C0CA"; 
my_custom_hex_to_bytes(hex, raw, 16); 

// parse raw binary stream bytes to 4 separate words 
boost::uint32_t word(0); 
byte_t* beg = raw; 
boost::spirit::qi::parse(beg, beg + 16, boost::spirit::qi::dword, word)) 

ACTUALIZACIÓN: He encontrado pregunta similar, donde Joel de Guzmán confirma en su disponibilidad respuesta de analizadores binarios: Can Boost Spirit be used to parse byte stream data?

+0

Eso parece prometedor. ¡Gracias! – doppelfish

1

Lectura en ASN.1. Si puede describir los datos binarios en sus términos, puede usar varios kits disponibles. No para los débiles de corazón.

0

No hay nada que te impida escribir un analizador decente recursivo, por ejemplo, para datos binarios de la misma manera que lo harías con la herramienta manual de un analizador de texto. Si el formato que necesita leer no es demasiado complicado, esta es una forma razonable de proceder.

Por supuesto, si el formato es muy simple, puede echar un vistazo a Reading binary file defined by a struct y preguntas similares.

No conozco ningún generador de analizadores para la entrada de texto, aunque también son posibles.


En el caso de que usted no está familiarizado con la codificación de programas de análisis con la mano, la cuestión de forma canónica es Learning to write a compiler. El Crenshaw tutorial (y in PDF) es una lectura rápida.

+0

Bueno, yo * estoy * esencialmente escribiendo un analizador de esa manera. A mano, eso es. ¿Pero soy la primera persona en la tierra en hacer esto? – doppelfish

2

El analizador Construct, escrito en Python, ha realizado un trabajo interesante en este campo.

El proyecto ha tenido varios autores y períodos de estancamiento, pero a partir de 2017 parece estar más activo de nuevo.

+1

Parece que alguien recogió mantenimiento recientemente. También tienen [nuevos documentos] (http://construct.readthedocs.org/en/latest/). – dowski

0

Consulte también los buffers de protocolo de google.

+1

Esto es realmente un comentario, no una respuesta a la pregunta. Utilice "agregar comentario" para dejar comentarios al autor. – Thor

9

Kaitai Struct iniciativa han surgido recientemente para resolver exactamente esa tarea: generar analizadores binarios de una especificación. Puede proporcionar un esquema para la serialización de la estructura de datos arbitraria en un formato basado en JSON YAML/así:

meta: 
    id: my_struct 
    endian: le 
seq: 
    - id: some_int 
    type: u4 
    - id: some_string 
    type: str 
    encoding: UTF-8 
    size: some_int + 4 
    - id: another_int 
    type: u4 

compilar usando ksc (que proporcionan una implementación de referencia del compilador), y, voila, usted tiene un analizador en cualquier lenguaje de programación soportado, por ejemplo, en C++:

my_struct_t::my_struct_t(kaitai::kstream *p_io, kaitai::kstruct *p_parent, my_struct_t *p_root) : kaitai::kstruct(p_io) { 
    m__parent = p_parent; 
    m__root = this; 
    m_some_int = m__io->read_u4le(); 
    m_some_string = m__io->read_str_byte_limit((some_int() + 4), "UTF-8"); 
    m_another_int = m__io->read_u4le(); 
} 

o en Java:

private void _parse() throws IOException { 
    this.someInt = this._io.readU4le(); 
    this.someString = this._io.readStrByteLimit((someInt() + 4), "UTF-8"); 
    this.anotherInt = this._io.readU4le(); 
} 

Después de añadir que a su proyecto, que ofrece una API muy intuitivo así (un ejemplo en Java, pero apoyan más idiomas):

// given file.dat contains 01 00 00 00|41 42 43 44|07 01 00 00 

MyStruct s = MyStruct.fromFile("path/to/file.dat"); 
s.someString() // => "ABCD" 
s.anotherInt() // => 263 = 0x107 

Es compatible con diferente orden de bits, estructuras condicionales, subestructuras, etc, y mucho más. Se pueden analizar estructuras de datos bastante complejas, como PNG image file format o PE executable.