Wie komprimieren Sie ASCII-Zeichenfolgen in weniger Bytes?


12

Ich arbeite mit einem eingebetteten Gerät mit einem eindeutigen Protokoll, das Nachrichten an andere Geräte sendet, und erstelle eine Anwendung, die die gesendeten Pakete analysiert. Jedes Paket enthält 8 Bytes. Das Protokoll ist so definiert, dass das erste Byte der Header und die restlichen 7 Bytes die Daten sind.

Sie versuchen, eine bestimmte ID-Zeichenfolge zu übergeben, aber die ID-Zeichenfolge ist 8 Zeichen lang (ASCII), sodass sie nicht in 7 Byte passt.

Mein Kollege sagte mir, dass sie die 8 ASCII-Bytes der ursprünglichen Zeichenfolge in eine Ganzzahl (Dezimalzahl) umwandeln und mir 4 Bytes davon senden werden. Sie sagten mir, ich sollte in der Lage sein, die ursprüngliche Zeichenfolge aus den 4 Bytes zu erhalten. Es fällt mir schwer, mich darauf einzulassen.

Wenn Sie also eine ID-Zeichenfolge wie "IO123456" haben, ist das 0x49 0x4f 0x31 0x32 0x33 0x34 0x35 0x36 in ASCII ? Vermisse ich etwas oder täuscht sich mein Kollege? Ich verstehe, dass dies eine wirklich bizzare Frage ist, aber im Ernst, das ergibt für mich keinen Sinn.


1
Jedes ASCII-Zeichen benötigt nur 7 Bits, sodass eine Zeichenfolge mit 8 ASCII-Zeichen in der Tat in 8 * 7 Bits - 7 Bytes - gespeichert werden kann.
Luiscubal

Antworten:


17

Ist die ID immer in der Form: IO123456? Ihr Kollege könnte bedeuten, dass er nur den numerischen Teil sendet, der problemlos in 4 Bytes passt, wobei der "IO" -Teil weggelassen wird.


1
Das war's. Die ersten zwei Bytes sind immer in Buchstaben und der Rest sind in Zahlen, so dass es leicht in 4 Bytes passen könnte, wie Sie sagten. Obwohl ich nicht weiß, woher die willkürliche Anzahl von 4 Bytes kommt, weil 999999 in hex F423F ist, also höchstens 3 Bytes ..
l46kok

5
@ l46kok: 3-Byte-Ganzzahlen (24-Bit-Ganzzahlen) sind sehr selten, daher ist es für sie wahrscheinlich einfacher, sie als 32-Bit-Ganzzahlen (4-Byte-Ganzzahlen) zu senden. Ich wäre nicht völlig überrascht, wenn Sie es in der nativen Darstellung (Bytereihenfolge) des eingebetteten Geräts erhalten.
Bart van Ingen Schenau

16

Wenn die ersten beiden Zeichen nicht konstant sind (sondern immer Buchstaben sind) und die restlichen sechs Zeichen immer Zahlen sind, kann eine Zeichenfolge wie "IO123456" in 5 Bytes gepackt werden, indem die Zahlen in das binärcodierte Dezimalformat (BCD) konvertiert werden:

IO123456 -> 0x49 0x4f 0x31 0x32 0x33 0x34 0x35 0x36
             |    |      \   /     \   /     \   /
            0x49 0x4f     0x12      0x34      0x56

Wenn es eine begrenzte Anzahl möglicher Bezeichner gibt (die ersten beiden Buchstaben), können Sie diese in eine Zahl kodieren und diese stattdessen senden (solange es nicht mehr als 256 Kombinationen gibt), z. B .:

IO -> 0x00
RD -> 0x01
WT -> 0x02
   ...
AB -> 0x10
   ...
ZZ -> 0xff

so dass der ursprüngliche String ohne Informationsverlust in 4 Bytes gepackt wird:

IO123456 -> 0x49 0x4f 0x31 0x32 0x33 0x34 0x35 0x36
              \    /     \   /     \   /     \   /
               0x00       0x12      0x34      0x56

Natürlich kann dieser Vorgang auch umgekehrt werden, um die ursprüngliche ID-Zeichenfolge zu erhalten.


3

Wenn die Zeichenfolge eine beliebige Folge von Zeichen sein kann:

  • Wenn Sie sicher sein können, dass Ihre Zeichenfolgen nicht das höchstwertige Bit in jedem Byte verwenden, können Sie jedes auf sieben Bits reduzieren und die verbleibenden 56 Bits mit bitweisen Operationen in die verfügbaren 56 Bits verschieben.

  • Wenn es sich bei den Zeichenfolgen nur um Buchstaben und Ziffern handelt, erstellen Sie eine 6-Bit-Darstellung dieser Menge und erstellen Sie eine 48-Bit-Zeichenfolge als Ihre Kennung.

Wenn das Format immer zwei Buchstaben gefolgt von einer Ziffernfolge ist:

  • Lassen Sie die ersten beiden Bytes in Ruhe und kodieren Sie die Zahl in eine 6-Byte-Ganzzahl. IO123456wird 0x49 0x4f 0x01E240.

  • Lassen Sie die ersten beiden Bytes in Ruhe und packen Sie die Ziffern als binär codierte Dezimalzahl . IO123456wird 0x49 0x4f 0x12 0x34 0x56.


1

Aus dem Kontext der hier gestellten Frage geht hervor, dass es sich um ein industrielles Protokoll namens HART handelt. Mit diesem Protokoll können die ASCII-Zeichen auf einzigartige Weise umbrochen werden. Es heißt Packed-ASCII. Aber immer noch packt es die 8 Zeichen nicht zu 4! Gemäß Packed-ASCII werden die 8 ASCII-Bytes in 6, 4 bis 3 usw. konvertiert.

In diesem Protokoll ist die Länge der Parameter in einer bestimmten Anforderung immer festgelegt. Die verbleibenden Zeichen müssen also mit Leerzeichen aufgefüllt werden. Trotzdem ist das alles HART-spezifisch. Wenn Sie bestätigen, dass Sie daran arbeiten, werde ich den genauen Ablauf des Packens und Auspackens festlegen.


0

Möglicherweise durch Konvertieren von '0123456' in eine lange Ganzzahl.

Dies würde jedoch nur für numerische IDs funktionieren.

Ein anderes mögliches Schema wäre die Konvertierung Ihrer 7- in 6-Bit-ECMA-1-Codierung, wodurch Sie eine 6-Byte-Zeichenfolge erhalten, aber Sie wären auf den Zeichensatz mit Ziffern in Großbuchstaben und einen begrenzten Satz von Interpunktionszeichen beschränkt.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.