2010-02-01 23 views
6

Tôi có một chương trình Java phát ra, trong định dạng thập lục phân được phân tách bằng dấu cách, 16 byte của gói dữ liệu thô nhận được qua mạng. Vì tôi không muốn thay đổi mã đó, tôi đang tạo kết quả cho một kịch bản Perl, về mặt lý thuyết, có thể chỉ đơn giản là unpack điều này từ STDIN thành các biến dễ nhận biết. Sau đây là một mẫu của các dòng đầu vào tập tin Perl của tôi:Làm cách nào để phân tích cú pháp các chuỗi thập phân STDIN được phân cách bằng dấu cách trong Perl?

 
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---| 

(c là cho char/byte, int cho biến số nguyên 16bit)

ban đầu tôi muốn sử dụng unpack để sạch tách mỗi đầu vào dòng vào các biến mà tôi cần. Tuy nhiên, vì không gian phân cách trong chuỗi, tôi không chắc chắn làm thế nào để xử lý nó (tôi có thể sử dụng 'A' làm mẫu, nhưng sau đó tôi cũng có thể chỉ cần sử dụng chia!)

Có cách nào thanh lịch không sử dụng unpack()? Tôi không phải là một bậc thầy Perl, nhưng cách khác là, như tôi đã đề xuất trước đây, sử dụng split và sau đó chuyển đổi thủ công từng hex thành một byte, và sau đó sử dụng thao tác bit và mặt nạ để có được những gì tôi muốn. Bất kỳ đề xuất nào khác (nếu unpack không lưu ngày)?

Trả lời

8

Giả sử những ints là trong đơn đặt hàng lớn về cuối nhỏ, sử dụng

#! /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 

Nó bắt đầu bằng việc đóng gói trong các byte (C*) theo giá trị của họ. Mẫu unpack có các phần sau đây:

  • x5 bỏ qua lăm byte
  • C2 giải mã hai unsigned char giá trị
  • n7 giải mã Bảy 16-bit lớn-endian số nguyên unsigned

Output:

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

Bạn có thể làm cho nó trông đẹp hơn bằng cách nói 'map {hex} split' :) – friedo

+2

Hoặc thậm chí chỉ là' map hex, split' - gần như Haskell! –

+0

thực sự tôi đã xác nhận rằng các byte ở cuối nhỏ. khủng khiếp, khi chúng được gửi qua mạng, tôi đã nghĩ rằng nên có trong thứ tự mạng. Oh well, thay đổi duy nhất sau đó cần phải được giải nén "x5C2n7" để giải nén "x5C2v7", phải không? Và cảm ơn cho trả lời ... diễn đàn này là tuyệt vời – intiha

3

Nếu bạn muốn sử dụng giải nén trên dữ liệu chưa được giải nén, trước tiên bạn cần đóng gói lại. Và bạn sẽ cần phải loại bỏ các không gian trước khi bạn làm điều đó.

Nói cách khác,

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

Tôi thực sự là bạn se giải pháp này do sạch hơn của nó nhìn (tôi hiểu những gì mã đã làm) kết hợp với giải nén đề xuất ở trên. và tôi cũng có thể phân tích cú pháp dòng $ nếu mã java trích xuất một chuỗi lỗi. – intiha

Các vấn đề liên quan