Come dovrei rappresentare i dati binari?

3

Sto scrivendo un codice di serializzazione e mi sto chiedendo come gestire i dati binari. Come lo sto facendo in Python, il mio obiettivo è renderlo molto semplice, non richiede un sacco di overhead del programmatore, ecc.

Tre opzioni che sto considerando:

  1. I campi che saranno dati binari sono rappresentati come stringhe con codifica esadecimale. Quindi avresti qualcosa di simile:

    obj = {
       'foo': 100,
       'bar': [1, 2, 3, 4],
       'baz': "ab0123ffbbaa55",
    }
    
    ObjectSpec.loads(ObjectSpec(obj).dumps())
    

    ObjectSpec è la classe che determina come serializzare l'oggetto.

    • I pro: è facile da guardare, facile da creare oggetti letterali, facile da stampare.
    • Gli svantaggi: devi ricordarti di codificare in modo esadecimale i campi. Se hai dei byte, devi codificarli esadecimali prima del codice di serializzazione, quindi hex-decodificali. Se vuoi memorizzare gli oggetti, c'è un sovraccarico a meno che non decifri prima le stringhe.
  2. I campi sono stringhe di byte, ad esempio,

    obj = {
       'foo': 100,
       'bar': [1, 2, 3, 4],
       'baz': '\xab\x01#\xff\xbb\xaaU',
    }
    
    • I pro: meno overhead, sia nello spazio, sia nel non dover codificare hex se hai già byte.
    • I contro: più difficile da fare letterali, più difficile da stampare. Se accidentalmente lasci una stringa con codifica esadecimale, serializzerà la cosa sbagliata (la rappresentazione esadecimale invece della cosa stessa).
  3. I campi dati binari usano un tipo personalizzato, ad es. bson.Binary :

    from bson import Binary
    
    obj = {
       'foo': 100,
       'bar': [1, 2, 3, 4],
       'baz': Binary('\xab\x01#\xff\xbb\xaaU'),
    }
    
    • I pro: come il n. 2, ma delinea chiaramente anche i tipi binari.
    • I contro: come il n. 2, ad eccezione di più difficile per codificare accidentalmente la cosa sbagliata. Richiede il wrapping dei dati in un tipo solo per ottenere il codice di serializzazione per accettarlo, invece di lasciare i byte in.

Quale sarebbe l'approccio più sensato? C'è un'altra variante che è meglio?

    
posta Claudiu 15.03.2016 - 16:35
fonte

1 risposta

1

È possibile definire valori binari ed esadecimali in python, basta usare 0xff o 0b1001010101001 . Sono definiti come sottoclasse di int . La funzione chr e ord le legge molto chiaramente.

object = {
   "foo": 100 
   "bar": [1,2,3,4],
   "baz": 0xffaff34441faabc # i realy dont get what foo,bar and baz are so i dont really know what your string should represent.
}

Quindi usa gli operatori binari e lo spostamento binario a sinistra, binario a destra per gestirlo nel giusto ordine. per esempio inviando dati a 13 byte a qualche porto con sintassi immaginaria PORT: STOP: MESSAGE: 0xFF00737461636B65786368616E6765 , o invia "stackexchange" alla porta 255 , dove 0xff è porta, 0x00 è STOP, e il resto è un messaggio. Quindi la tua funzione dovrebbe essere qualcosa del genere, i primi 2 byte sono port, se next iz 0x00 quindi si divide e il resto "translate" in string.

Se vuoi testare in ambiente sicuro puoi usare
map(chr, [0x73,0x74,0x61,0x63,0x6B,0x65,0x78,0x63,0x68,0x61,0x6E,0x67,0x65])

    
risposta data 30.12.2016 - 19:27
fonte

Leggi altre domande sui tag