Как вы сжимаете строки ASCII в меньшее количество байтов?

12

Я работаю со встроенным устройством с уникальным протоколом, который отправляет сообщения на другие устройства, и я делаю приложение, которое анализирует отправленные пакеты. Каждый пакет содержит 8 байтов. Протокол определяется как первый байт заголовка, а остальные 7 байт - данные.

Они пытаются передать определенную строку идентификатора, но длина строки идентификатора составляет 8 символов (ASCII), поэтому она не помещается в 7 байтов.

Мой коллега сказал мне, что они собираются превратить 8 байтов ascii исходной строки в целое (десятичное) и отправить мне 4 байта. Мне сказали, что я смогу получить исходную строку из 4 байтов. Я с трудом могу обдумать это.

Так что, если у вас есть строка идентификатора, такая как «IO123456», это 0x49 0x4f 0x31 0x32 0x33 0x34 0x35 0x36 в ASCII. Как на самом деле вы можете сжать это в 4 байта, превратив его в целое число, и я могу получить исходную строку из него ? Я что-то упустил или мой коллега ошибается? Я понимаю, что это действительно странный вопрос, но это серьезно не имеет никакого смысла для меня.

l46kok
источник
1
Каждый символ ASCII занимает всего 7 бит, поэтому строка с 8 символами ASCII действительно может храниться в 8 * 7 битах - 7 байтов.
luiscubal

Ответы:

17

Идентификатор всегда в форме: IO123456? Что может означать ваш коллега, так это то, что он посылает только числовую часть, которая легко помещается в 4 байта, пропуская часть «IO».

Питер Б
источник
1
Это было оно. Первые два байта всегда в виде букв, а остальные в цифрах, так что он может легко уместиться в 4 байта, как вы сказали. Хотя я не знаю, откуда взялась произвольная цифра 4 байта, потому что 999999 в шестнадцатеричном формате - это F423F, так что это максимум 3 байта ..
l46kok
5
@ l46kok: 3-байтовые (24-битные) целые числа встречаются очень редко, поэтому им, вероятно, проще отправить его как 32-битное (4-байтовое) целое число. Я не был бы полностью удивлен, если бы вы получили его в нативном представлении (порядок байтов) встроенного устройства.
Барт ван Инген Шенау
16

Если первые два символа не являются постоянными (но всегда являются буквами), а оставшиеся шесть символов всегда являются числами, строка типа «IO123456» может быть упакована в 5 байтов путем преобразования чисел в двоично-десятичный формат (BCD):

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

Если существует ограниченный набор возможных идентификаторов (первые две буквы), вы можете закодировать их в число и отправить вместо этого (при условии, что не более 256 комбинаций), например:

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

так что исходная строка упакована в 4 байта без потери информации:

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

Конечно, этот процесс также можно изменить, чтобы получить исходную строку идентификатора.

ProphetV
источник
3

Если строка может быть любой последовательностью символов:

  • Если вы можете быть уверены, что ваши строки не используют самый старший бит в каждом байте, вы можете сократить каждый из них до семи бит и использовать побитовые операции, чтобы сдвинуть оставшиеся 56 бит в те 56 бит, которые у вас есть.

  • Если строки представляют собой только буквы и цифры, придумайте 6-битное представление только этого набора и сделайте 48-битную строку вашего идентификатора.

Если формат всегда состоит из двух букв, за которыми следует строка цифр:

  • Оставьте первые два байта в покое и закодируйте число в шестибайтовое целое число. IO123456становится 0x49 0x4f 0x01E240.

  • Оставьте первые два байта в покое и упакуйте цифры в двоично-десятичный код . IO123456становится 0x49 0x4f 0x12 0x34 0x56.

Blrfl
источник
1

Из контекста вопроса, размещенного здесь, он указывает на некоторый промышленный протокол под названием HART. Этот протокол имеет уникальный способ переноса символов ASCII. Это называется Packed-ASCII. Но все равно он не упаковывает 8 символов в 4! Согласно Packed-ASCII, 8 байтов ASCII преобразуются в 6. 4 к 3 и так далее.

В этом протоколе длина параметров в определенном запросе всегда фиксирована. Таким образом, оставшиеся символы должны быть дополнены пробелами. Тем не менее, это все вещи, специфичные для HART. Если вы подтвердите, что работаете над этим, я поставлю точную процедуру упаковки и распаковки.

OnkarK
источник
0

Возможно, преобразовав '0123456' в длинное целое число.

Но это будет работать только для числовых идентификаторов.

Другой возможной схемой будет преобразование вашей 7–6-битной кодировки ECMA-1, которая даст вам строку из шести байтов, но вы будете ограничены набором символов цифрами в верхнем регистре и ограниченным набором знаков пунктуации.

Джеймс Андерсон
источник