Jak kompresujesz ciągi ASCII do mniejszej liczby bajtów?

12

Pracuję z urządzeniem osadzonym z unikalnym protokołem, który wysyła wiadomości do innych urządzeń i tworzę aplikację, która analizuje wysłane pakiety. Każdy pakiet zawiera 8 bajtów. Protokół jest zdefiniowany jako gdzie pierwszy bajt to nagłówek, a pozostałe 7 bajtów to dane.

Próbują przekazać określony ciąg identyfikatora, ale ciąg identyfikatora ma długość 8 znaków (ASCII), więc nie zmieści się w 7 bajtach.

Mój kolega powiedział mi, że zamieni 8 bajtów ascii oryginalnego ciągu znaków na liczbę całkowitą (dziesiętną) i wyśle ​​mi 4 bajty. Powiedzieli mi, że powinienem być w stanie uzyskać oryginalny ciąg z 4 bajtów. Trudno mi się na tym skupić.

Więc jeśli masz ciąg identyfikatora, taki jak „IO123456”, to jest to 0x49 0x4f 0x31 0x32 0x33 0x34 0x35 0x36 w ASCII .. Jak do licha możesz skompresować to w 4 bajtach, zamieniając go na liczbę całkowitą i mogę uzyskać z niego oryginalny ciąg ? Czy coś pomijam, czy mój kolega się myli? Rozumiem, że to naprawdę dziwne pytanie, ale to poważnie nie ma dla mnie żadnego sensu.

L46kok
źródło
1
Każdy znak ASCII zajmuje tylko 7 bitów, więc ciąg zawierający 8 znaków ASCII można rzeczywiście zapisać w 8 * 7 bitach - 7 bajtach.
luiscubal

Odpowiedzi:

17

Czy identyfikator ma zawsze postać: IO123456? Twój kolega może oznaczać, że wysyła tylko część numeryczną, która z łatwością mieści się w 4 bajtach, pomijając część „IO”.

Pieter B.
źródło
1
To było to. Pierwsze dwa bajty są zawsze literami, a reszta cyframi, więc można łatwo zmieścić 4 bajty, jak powiedziałeś. Chociaż nie wiem, skąd wzięła się dowolna liczba 4 bajtów, ponieważ 999999 w zapisie szesnastkowym to F423F, więc to maksymalnie 3 bajty ..
l46kok
5
@ l46kok: 3-bajtowe (24-bitowe) liczby całkowite są bardzo rzadkie, więc prawdopodobnie łatwiej jest im wysłać jako 32-bitową (4-bajtową) liczbę całkowitą. Nie byłbym całkowicie zaskoczony, gdybyś dostał go w natywnej reprezentacji (kolejności bajtów) wbudowanego urządzenia.
Bart van Ingen Schenau
16

Jeśli pierwsze dwa znaki nie są stałe (ale zawsze są literami), a pozostałe sześć znaków jest zawsze cyframi, ciąg taki jak „IO123456” można spakować do 5 bajtów, konwertując liczby na format dziesiętny (BCD):

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

Jeśli istnieje ograniczony zestaw możliwych identyfikatorów (pierwsze dwie litery), możesz zakodować je w liczbie i wysłać zamiast tego (o ile nie ma więcej niż 256 kombinacji), np .:

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

dzięki czemu oryginalny ciąg jest pakowany w 4 bajty bez utraty informacji:

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

Oczywiście proces ten można również odwrócić, aby uzyskać oryginalny ciąg identyfikatora.

Prorok
źródło
3

Jeśli ciąg może być dowolną sekwencją znaków:

  • Jeśli możesz być pewien, że łańcuchy nie wykorzystują najbardziej znaczącego bitu w każdym bajcie, możesz pociąć każdy z nich na siedem bitów i użyć operacji bitowych, aby przesunąć pozostałe 56 bitów na 56 dostępnych bitów.

  • Jeśli ciągi są tylko literami i cyframi, wymyśl 6-bitową reprezentację tylko tego zestawu i utwórz 48-bitowy ciąg identyfikatora.

Jeśli format ma zawsze dwie litery, po których następuje ciąg cyfr:

  • Pozostaw dwa pierwsze bajty w spokoju i zakoduj liczbę w sześciobajtową liczbę całkowitą. IO123456staje się 0x49 0x4f 0x01E240.

  • Pozostaw dwa pierwsze bajty w spokoju i spakuj cyfry w postaci dziesiętnej kodowanej binarnie . IO123456staje się 0x49 0x4f 0x12 0x34 0x56.

Blrfl
źródło
1

W kontekście zamieszczonego tutaj pytania wskazuje on na jakiś przemysłowy protokół o nazwie HART. Ten protokół ma unikalny sposób zawijania znaków ASCII. Nazywa się to jako Packed-ASCII. Ale nadal nie pakuje 8 znaków do 4! Zgodnie z Packed-ASCII, 8 bajtów ASCII jest konwertowanych na 6,4 do 3 itd.

W tym protokole długość parametrów w określonym żądaniu jest zawsze stała. Pozostałe postacie muszą zostać uzupełnione przez spacje. Mimo to wszystkie te rzeczy są specyficzne dla HART. Jeśli potwierdzisz, że nad tym pracujesz, przedstawię dokładną procedurę pakowania i rozpakowywania.

OnkarK
źródło
0

Prawdopodobnie poprzez konwersję „0123456” na długą liczbę całkowitą.

Ale działałoby to tylko w przypadku identyfikatorów numerycznych.

Innym możliwym schematem byłaby konwersja 7-do 6-bitowego kodowania ECMA-1, co dałoby Ci sześciobajtowy ciąg znaków, ale byłbyś ograniczony do zestawu znaków zawierającego duże litery i ograniczonego zestawu znaków interpunkcyjnych.

James Anderson
źródło