ASCII dizelerini daha az bayta nasıl sıkıştırırsınız?


12

Diğer cihazlara mesaj gönderen benzersiz bir protokol ile gömülü bir cihazla çalışıyorum ve gönderilen paketleri ayrıştıran bir uygulama yapıyorum. Her paket 8 bayt taşır. Protokol, ilk baytın başlık olduğu ve kalan 7 baytın da veri olduğu şeklinde tanımlanır.

Belirli bir kimlik dizesini geçmeye çalışıyorlar, ancak kimlik dizesi 8 karakter uzunluğunda (ASCII) olduğundan 7 bayta sığmayacak.

Meslektaşımın söylediği, orijinal dizenin 8 ascii baytını tamsayı (ondalık) haline getirecek ve bana 4 bayt gönderecekleridir. Bana 4 bayt orijinal dize almak gerekir söyledi. Bu konuda kafamı sarmakta zorlanıyorum.

Yani "IO123456" gibi bir kimlik dizeniz varsa, bu ASCII'de 0x49 0x4f 0x31 0x32 0x33 0x34 0x35 0x36 .. Yeryüzünde bunu bir tamsayıya çevirerek 4 baytta nasıl sıkıştırabilir ve ondan orijinal dizeyi alabilirim ? Bir şey mi kaçırıyorum yoksa meslektaşım yanılıyor mu? Bunun gerçekten tuhaf bir soru olduğunu anlıyorum ama bu benim için ciddi bir anlam ifade etmiyor.


1
Her ASCII karakteri sadece 7 bit alır, bu nedenle 8 ASCII karakterli bir dize 8 * 7 bit - 7 baytta saklanabilir.
luiscubal

Yanıtlar:


17

Kimlik her zaman şu biçimde mi: IO123456? Meslektaşınızın anlamı, "IO" bölümünü atlayan 4 bayta kolayca uyan sayısal kısmı göndermesidir.


1
Bu oydu. İlk iki bayt her zaman harflerle ve geri kalanlar rakamlarla gösterilir, böylece dediğin gibi 4 bayta kolayca sığabilir. Her ne kadar 4 bayt keyfi olarak nereden geldi bilmiyorum, çünkü hex 999999 F423F olduğundan en fazla 3 bayt ..
l46kok

5
@ l46kok: 3 bayt (24 bit) tamsayılar çok nadirdir, bu yüzden 32 bit (4 bayt) tamsayı olarak göndermeleri daha kolaydır. Gömülü cihazın yerel temsilinde (bayt sırası) alırsanız tamamen şaşırmam.
Bart van Ingen Schenau

16

İlk iki karakter sabit değilse (ancak her zaman harfse) ve geri kalan altı karakter her zaman sayıysa, "IO123456" gibi bir dize, sayılar ikili kodlu ondalık (BCD) biçimine dönüştürülerek 5 bayta paketlenebilir :

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

Sınırlı sayıda olası tanımlayıcı (ilk iki harf) varsa, bunları bir sayıya kodlayabilir ve bunun yerine gönderebilirsiniz (256'dan fazla kombinasyon olmadığı sürece), örneğin:

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

böylece orijinal dize hiçbir bilgi kaybı olmadan 4 bayt içine paketlenir:

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

Tabii ki bu işlem orijinal kimlik dizesini almak için tersine çevrilebilir.


3

Dize herhangi bir karakter dizisi olabilirse:

  • Dizelerinizin her baytta en önemli biti kullanmadığından emin olabilirseniz, her birini yedi bite kadar kesebilir ve kalan 56 biti mevcut 56 bite kaydırmak için bitsel işlemleri kullanabilirsiniz.

  • Dizeler yalnızca harf ve rakamsa, yalnızca bu kümenin 6 bitlik bir gösterimini yapın ve tanımlayıcınızın 48 bitlik bir dizesini oluşturun.

Biçim her zaman iki harften sonra bir rakam dizesi geliyorsa:

  • İlk iki baytı yalnız bırakın ve sayıyı altı baytlık bir tamsayıya kodlayın. IO123456olur 0x49 0x4f 0x01E240.

  • İlk iki baytı yalnız bırakın ve rakamları ikili kodlu ondalık olarak paketleyin . IO123456olur 0x49 0x4f 0x12 0x34 0x56.


1

Burada yayınlanan sorunun bağlamından, HART adı verilen bir endüstriyel protokole işaret ediyor. Bu protokol ASCII karakterleri sarma benzersiz bir yol vardır. Paketli ASCII olarak adlandırılır. Ama yine de 8 karakteri 4'e koymuyor! Packed-ASCII'ye göre, 8 ASCII baytı 6.4 ila 3'e dönüştürülür.

Bu protokolde, belirli bir istekte parametrelerin uzunluğu her zaman sabittir. Bu nedenle, kalan karakterlerin Space karakterleri tarafından doldurulması gerekir. Yine de, bu her şey HART'a özgüdür. Bu konuda çalıştığınızı onaylarsanız, paketleme ve ambalajlama işleminin tam prosedürünü koyacağım.


0

Muhtemelen '0123456' yı uzun bir tamsayıya dönüştürerek.

Ancak bu yalnızca sayısal kimlikler için kullanılabilir.

Başka bir olası şema, size altı baytlık bir dize verecek olan 7'den 6 bitlik ECMA-1 kodlamanıza dönüştürmek olacaktır, ancak karakter kümesini sayılar büyük harflerle ve sınırlı noktalama işareti kümesiyle sınırlandırırsınız.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.