Bagaimana Anda mengompres string ASCII menjadi lebih sedikit byte?

12

Saya bekerja dengan perangkat tertanam dengan protokol unik yang mengirim pesan ke perangkat lain dan saya membuat aplikasi yang mem-parsing paket yang dikirim. Setiap paket membawa 8 byte. Protokol didefinisikan sebagai tempat byte pertama adalah header dan sisa 7 byte adalah data.

Mereka mencoba untuk melewatkan string ID tertentu tetapi string ID panjangnya 8 karakter (ASCII) sehingga tidak akan muat dalam 7 byte.

Apa yang dikatakan oleh kolega saya adalah bahwa mereka akan mengubah 8 ascii byte dari string asli menjadi integer (desimal) dan mengirimkan saya 4 byte darinya. Mereka mengatakan kepada saya bahwa saya harus bisa mendapatkan string asli dari 4 byte. Saya mengalami kesulitan membungkus kepala saya di sekitar ini.

Jadi jika Anda memiliki string ID seperti "IO123456", itu 0x49 0x4f 0x31 0x32 0x33 0x34 0x35 0x36 di ASCII .. Bagaimana bisa Anda mengompresnya dalam 4 byte dengan mengubahnya menjadi bilangan bulat dan saya bisa mendapatkan string asli dari itu ? Apakah saya melewatkan sesuatu atau kolega saya salah? Saya mengerti ini adalah pertanyaan yang sangat aneh tapi ini serius tidak masuk akal bagi saya.

lk
sumber
1
Setiap karakter ASCII hanya membutuhkan 7 bit, jadi string dengan 8 karakter ASCII memang dapat disimpan dalam 8 * 7 bit - 7 byte.
Luiscubal

Jawaban:

17

Apakah ID selalu dalam bentuk: IO123456? Maksud rekan Anda adalah bahwa ia hanya mengirim bagian numerik, yang cocok dengan mudah dalam 4 byte menghilangkan bagian "IO".

Pieter B
sumber
1
Ini dia. Dua byte pertama selalu dalam huruf dan sisanya dalam angka, sehingga bisa dengan mudah masuk dalam 4 byte seperti yang Anda katakan. Meskipun saya tidak tahu dari mana angka acak 4 byte berasal, karena 999999 dalam hex adalah F423F jadi paling banyak 3 byte ..
l46kok
5
@ l46kok: integer 3-byte (24-bit) sangat jarang, jadi mungkin lebih mudah bagi mereka untuk mengirimkannya sebagai integer 32-bit (4-byte). Saya tidak akan sepenuhnya terkejut jika Anda mendapatkannya di representasi asli (urutan byte) dari perangkat yang tertanam.
Bart van Ingen Schenau
16

Jika dua karakter pertama tidak konstan (tetapi selalu huruf) dan keenam karakter lainnya selalu berupa angka, string seperti "IO123456" dapat dimasukkan ke dalam 5 byte dengan mengonversi angka ke dalam format binary-coded desimal (BCD):

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

Jika ada set terbatas pengidentifikasi yang mungkin (dua huruf pertama), Anda dapat menyandikan ini ke dalam angka dan mengirimnya sebagai gantinya (selama tidak ada lebih dari 256 kombinasi), misalnya:

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

sehingga string asli dikemas ke dalam 4 byte tanpa kehilangan informasi:

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

Tentu saja proses ini juga dapat dibalik untuk mendapatkan string ID asli.

NabiV
sumber
3

Jika string dapat berupa urutan karakter apa pun:

  • Jika Anda yakin string Anda tidak menggunakan bit yang paling signifikan di setiap byte, Anda dapat memotongnya menjadi tujuh bit dan menggunakan operasi bitwise untuk menggeser 56 bit yang tersisa ke dalam 56 bit yang tersedia.

  • Jika string hanya berupa huruf dan angka, buatlah representasi 6-bit dari set itu dan buat string 48-bit dari pengidentifikasi Anda.

Jika format selalu dua huruf diikuti oleh serangkaian angka:

  • Biarkan dua byte pertama saja dan mengkodekan angka ke dalam integer enam byte. IO123456menjadi 0x49 0x4f 0x01E240.

  • Biarkan dua byte pertama saja dan kemas digit sebagai desimal berkode biner . IO123456menjadi 0x49 0x4f 0x12 0x34 0x56.

Blrfl
sumber
1

Dari konteks pertanyaan yang diposting di sini, itu menunjuk ke beberapa protokol industri yang disebut HART. Protokol ini memiliki cara unik untuk membungkus karakter ASCII. Itu disebut sebagai Packed-ASCII. Tapi tetap saja itu tidak mengemas 8 karakter menjadi 4! Menurut Packed-ASCII, 8 byte ASCII dikonversi menjadi 6. 4 hingga 3 dan seterusnya.

Dalam protokol ini, panjang parameter dalam permintaan tertentu selalu diperbaiki. Jadi karakter yang tersisa perlu diisi oleh karakter Space. Namun, ini semua adalah HART-Spesifik. Jika Anda mengonfirmasi bahwa Anda sedang mengerjakan ini, saya akan memasukkan prosedur pengemasan & pembongkaran yang tepat.

OnkarK
sumber
0

Mungkin dengan mengubah '0123456' menjadi bilangan bulat panjang.

Tetapi ini hanya akan berfungsi untuk ID numerik.

Skema lain yang mungkin adalah untuk mengkonversi 7 sampai 6 bit ECMA-1 encoding Anda yang akan memberi Anda string Enam byte tetapi Anda akan dibatasi untuk set karakter ke angka huruf besar dan karakter tanda baca yang terbatas.

James Anderson
sumber