Como você comprime seqüências de caracteres ASCII em menos bytes?

12

Estou trabalhando com um dispositivo incorporado com um protocolo exclusivo que envia mensagens para outros dispositivos e estou criando um aplicativo que analisa os pacotes enviados. Cada pacote leva 8 bytes. O protocolo é definido como onde o primeiro byte é o cabeçalho e os 7 bytes restantes são os dados.

Eles estão tentando transmitir uma sequência de ID específica, mas a sequência de ID tem 8 caracteres (ASCII), portanto não caberá em 7 bytes.

O que meu colega me disse é que eles vão transformar os 8 bytes ASCII da string original em número inteiro (decimal) e me enviar 4 bytes dela. Eles me disseram que eu deveria conseguir a string original dos 4 bytes. Estou tendo dificuldades para entender isso.

Portanto, se você tiver uma cadeia de caracteres de identificação como "IO123456", será 0x49 0x4f 0x31 0x32 0x33 0x34 0x35 0x36 em ASCII ? Estou faltando alguma coisa ou meu colega está enganado? Entendo que essa é uma pergunta realmente bizarra, mas isso não faz muito sentido para mim.

l46kok
fonte
1
Cada caractere ASCII leva apenas 7 bits, portanto, uma string com 8 caracteres ASCII pode realmente ser armazenada em 8 * 7 bits - 7 bytes.
luiscubal

Respostas:

17

O ID está sempre no formato: IO123456? O que seu colega pode dizer é que ele envia apenas a parte numérica, que cabe facilmente em 4 bytes, omitindo a parte "IO".

Pieter B
fonte
1
Era isso. Os dois primeiros bytes estão sempre em letras e o restante em números, portanto pode caber facilmente em 4 bytes, como você disse. Embora eu não sei onde o número arbitrariamente de 4 bytes veio, porque 999999 em hexadecimal é F423F por isso é 3 bytes no máximo ..
l46kok
5
@ l46kok: números inteiros de 3 bytes (24 bits) são muito raros, por isso é provavelmente mais fácil enviá-lo como um número inteiro de 32 bits (4 bytes). Eu não ficaria completamente surpreso se você obtê-lo na representação nativa (ordem dos bytes) do dispositivo incorporado.
Bart van Ingen Schenau
16

Se os dois primeiros caracteres não forem constantes (mas sempre letras) e os seis caracteres restantes forem sempre números, uma sequência como "IO123456" poderá ser compactada em 5 bytes, convertendo os números no formato BCD ( decimal em código binário ):

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

Se houver um conjunto limitado de identificadores possíveis (as duas primeiras letras), você poderá codificá-los em um número e enviá-lo (desde que não haja mais de 256 combinações), por exemplo:

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

para que a cadeia original seja compactada em 4 bytes sem perda de informações:

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

Obviamente, esse processo também pode ser revertido para obter a sequência de ID original.

Profeta
fonte
3

Se a sequência puder ser qualquer sequência de caracteres:

  • Se você tiver certeza de que suas seqüências não usam o bit mais significativo em cada byte, reduza cada uma delas para sete bits e use operações bit a bit para mudar os 56 bits restantes para os 56 bits disponíveis.

  • Se as strings forem apenas letras e dígitos, crie uma representação de 6 bits desse conjunto e faça uma string de 48 bits do seu identificador.

Se o formato for sempre duas letras seguidas por uma sequência de dígitos:

  • Deixe os dois primeiros bytes em paz e codifique o número em um número inteiro de seis bytes. IO123456torna-se 0x49 0x4f 0x01E240.

  • Deixe os dois primeiros bytes em paz e empacote os dígitos como decimal codificado em binário . IO123456torna-se 0x49 0x4f 0x12 0x34 0x56.

Blrfl
fonte
1

Do contexto da pergunta postada aqui, ele aponta para algum protocolo industrial chamado HART. Este protocolo possui uma maneira exclusiva de agrupar os caracteres ASCII. É chamado como ASCII compactado. Mas ainda não comporta os 8 caracteres para 4! De acordo com o Packed-ASCII, os 8 bytes ASCII são convertidos em 6. 4 a 3 e assim por diante.

Neste protocolo, o comprimento dos parâmetros em uma determinada solicitação é sempre fixo. Portanto, os caracteres restantes precisam ser preenchidos por caracteres de espaço. Ainda assim, tudo isso é específico ao HART. Se você confirmar que está trabalhando nisso, colocarei o procedimento exato de embalagem e descompactação.

OnkarK
fonte
0

Possivelmente convertendo '0123456' para um número inteiro longo.

Mas isso funcionaria apenas para IDs numéricos.

Outro esquema possível seria converter sua codificação ECMA-1 de 7 a 6 bits, que forneceria uma sequência de seis bytes, mas você estaria limitado ao conjunto de caracteres para numerar letras maiúsculas e um conjunto limitado de caracteres de pontuação.

James Anderson
fonte