Compressione esadecimale veloce e semplice

-2

Sto lavorando su un progetto che richiede una connessione TCP tra un client e un server. Il protocollo corrente codifica i dati in esadecimale e quindi li invia. Tuttavia, esadecimale aumenta la lunghezza del carico utile che non è realmente ottimale dal punto di vista della rete.

Hex segue uno schema piuttosto prevedibile con caratteri ripetuti ecc. Stavo cercando un algoritmo di compressione veloce e preferibilmente semplice che funzioni molto bene con le stringhe con codifica esadecimale. Mi sono guardato intorno per un po 'ma non sono stato in grado di trovare una soluzione decente. Qualche idea?

    
posta Awn 07.10.2016 - 09:18
fonte

2 risposte

3

The current protocol encodes the data into hex

Quale protocollo? TCP certamente non lo fa.

Credo che in realtà ti riferisci alla codifica binaria in testo . Questo è un metodo per convertire dati binari in dati testuali in modo che possano essere inviati su sistemi che consentono solo testo.

Hex stesso è solo un modo per presentare un numero per la visualizzazione, in realtà non destinato alla memorizzazione o alla trasmissione. Tutto ciò che è memorizzato nel tuo computer o trasmesso al tuo computer può essere presentato come HEX (indipendentemente dalla codifica).

Questo è ciò che fa un editor HEX. Guarda il numero e lo mostra in HEX. Non decodifica. Non capisce nemmeno come si debba vedere il file. Guarda il file come un numero e ti mostra il numero in un modo che rende facile vedere i limiti dei byte. Potrebbe altrettanto facilmente mostrarlo come 1 e 0. Prenderà solo più spazio sullo schermo.

Le due idee si scontrano quando prendi la presentazione HEX come una codifica. Questo può loop per sempre. Ad esempio, un binario 1 è 1 in esadecimale. Ma per mostrare che 1 in ascii usi il codice ascii per 1 che è un numero completamente diverso (49 o 31 in esadecimale). Quindi ora stai memorizzando 31 quando vuoi dire uno. Ma se vuoi mostrare 31 allora stai memorizzando 33 e 31. E così via e così via.

Alcuni mezzi di trasmissione dei dati consentono solo il testo. TCP consente il binario completo, quindi qualunque protocollo tu stia parlando, non è TCP. Ciò potrebbe significare, ad esempio, che non è possibile utilizzare i caratteri ascii estesi oltre il 127.

Un modo per ovviare a questa limitazione è codificare i dati binari in modo da evitare i caratteri estesi. Codifica in HEX significa che usi solo 16 simboli. Quando hai a disposizione 127 simboli, usare solo 16 non è molto efficace.

Si prega di capire che il testo è binario. Il testo è semplicemente un certo insieme di codifiche (ascii, ebcdic, UTF-8 da unicode e molti altri ). Il binario è tutto questo e qualsiasi altra cosa. L'unico motivo per cui un editor di testo sa visualizzare un file di testo come un file di testo è perché presuppone che sia un file di testo e che lo decodifichi per decodificarlo. Apri un file eseguibile nel blocco note o vi qualche volta. Vedrai alcune sciocchezze interessanti sullo schermo.

Hex follows a pretty predictable pattern with repeating characters etc. I was looking for a fast and preferably simple compression algorithm that works very well with Hex encoded strings. I've looked around for a while but I haven't been able to find a decent solution. Any thoughts?

La soluzione ideale per questo sarebbe smettere di codificare in esadecimale e trasmettere in binario. TCP può farlo bene. Se sei bloccato andando oltre il protocollo di solo testo ci sono sicuramente codifiche migliori di HEX, a patto che il protocollo permetta più di 16 simboli esadecimali.

Un tipico esempio di un protocollo di trasporto di solo testo è l'e-mail (certamente non TCP). Non riesco a digitare un file binario nel corpo di un'email. Posso codificarne uno in base64 e incollarlo nel corpo di un'email. L'unica ragione che è migliore della codifica esadecimale è perché utilizza più simboli disponibili. Diamine, non potrei digitare nient'altro che 1 e 0 ma sarebbe ancora meno efficiente. Idealmente, vuoi essere in grado di utilizzare tutti i simboli che hai a disposizione.

Dal tuo commento:

By protocol I mean the high level communication protocol that was implemented, not TCP. The reason for encoding is the message based system that was implemented basically just uses a terminating character. I could change that and then just send it as raw bytes maybe. – Eclipse

In questo caso usa una sequenza di escape per assicurarti di rimuovere il carattere di chiusura. Dì che il tuo carattere di chiusura era! Ogni volta che c'è un reale! nei tuoi dati sostituiscile con un ~ @. Un vero ~ sostituirlo con ~~. Un @ effettivo sarà espresso come @.

    String rawData = "abc~@!xyz";
    String encodedData = rawData
            .replaceAll("~", "~~")
            .replaceAll("!", "~@")
            ;
    String decodedData = encodedData
            // (?<!~) is a negitive look behind that ensures ~@! won't be taken as !!
            // see http://stackoverflow.com/a/7594029/1493294
            .replaceAll("(?<!~)~@", "!")
            .replaceAll("~~", "~")
            ;
    System.out.println(encodedData);
    assertEquals(rawData, decodedData);

Visualizza

abc~~@~@xyz
    
risposta data 07.10.2016 - 19:02
fonte
0

Hex follows a pretty predictable pattern with repeating characters etc.

Non è vero, a meno che i dati sottostanti (rappresentati in esadecimale) abbiano un modello prevedibile.

Se i dati hanno uno schema prevedibile, allora è comprimibile. Potresti (dovresti) comprimere i dati per primi (usando qualsiasi algoritmo di compressione adatto, non necessariamente un algoritmo specifico per le esadecimali), e poi (se hai bisogno di codifica esadecimale) codifica esadecimale dei dati compressi.

    
risposta data 07.10.2016 - 12:53
fonte

Leggi altre domande sui tag