2010-02-01 15 views
6

Uzaydan ayrı onaltılık biçimde, ağ üzerinden alınan 16 baytlık işlenmemiş paket halinde tüküren bir Java programım var. Bu kodu değiştirmek istemediğimden, sonucu teorik olarak unpack'un STDIN'dan tanınabilir değişkenlere dönüştürebileceği bir Perl betiğine pipetliyorum. Perl dosyasına hat girişi, bir örnek aşağıda verilmektedir:Perl'de açılmadan ayrılmış STDIN altıgen dizeleri nasıl ayrıştırabilirim?

 
FF FF 09 7D 10 01 07 01 00 02 00 1D 00 00 00 00 00 06 00 07 00 
|--garbage-----|c--|c--|int---|int---|int---|int---|int---|int---|int---| 

Başlangıçta temiz her giriş ayırmak için unpack kullanmak istediğini

(c, karakter/bayt için 16 bit tamsayı değişken için int) ihtiyacım olan değişkenlere doğru Ancak, dizedeki boşluk sınırından dolayı, nasıl işleyeceğimi bilmiyorum ('A'yı bir şablon olarak kullanabilirim, ancak sonra da sadece bölme kullanabilirim!)

Zarif bir yol var mı? unpack() kullanıyor? Ben bir Perl ustası değilim, ama diğer yolu, daha önce önerdiğim gibi, split kullanın ve daha sonra her bir hex'i bir bayta dönüştürün ve sonra istediğimi elde etmek için bit manipülasyonları ve maskeler kullanın. Başka öneriler (unpack günü kaydetmezse)?

cevap

8

, Onların değerlerine göre bayt (C*) sermek suretiyle başlıyor

#! /usr/bin/perl 

use warnings; 
use strict; 

# for demo only 
*ARGV = *DATA; 

while (<>) { 
    my @fields = unpack "x5C2n7", 
       pack "C*", 
       map hex, split; 

    print "[", join("][" => @fields), "]\n"; 
} 

__DATA__ 
FF FF 09 7D 10 01 07 01 00 02 00 1D 00 00 00 00 00 06 00 07 00 

kullanın.

:

  • x5 beş bayt
  • C2 deşifre iki unsigned char değerleri
  • n7 deşifre yedi 16-bit big-endian işaretsiz tamsayılar

Çıktı atlar: unpack şablonu aşağıdaki bölümden oluşur

$ ./dump-packets 
[1][7][256][512][7424][0][0][1536][1792]
+0

Harita {hex} split ':) – friedo

+2

diyerek daha güzel görünebilir veya hatta sadece' map hex, split '- neredeyse Haskell! –

+0

aslında baytların küçük bir endian olduğunu doğruladım. Wierd, bir ağ üzerinden gönderildikçe, ağ düzeninde olması gerektiğini düşünürdüm. Oh, peki, sadece "x5C2v7" paketini açmak için "x5C2n7" paketini açmanız gerekiyor, değil mi? Ve cevap için teşekkürler ... Bu forum harika – intiha

3

Paketin açılmamış verilerinizi açmak isterseniz, önce tekrar paketlemeniz gerekir. Ve bunu yapmadan önce boşlukları kaldırmanız gerekir. Başka bir deyişle

, bu int büyük endian sırayla olduğunu varsayarsak

$line =~ tr/ //d;   # remove spaces 
$line = pack 'H*', $line; # convert hex to binary 
# Now you can use unpack. 
+0

Ben aslında Bu çözüm, daha temiz bir görünümle (kodun ne yaptığını anladım) yukarıda belirtilen paket açma işlemiyle birleştirildi. Ayrıca java kodu bir hata dizesi yayıyorsa $ çizgisini de ayrıştırabilirim. – intiha