2013-02-16 21 views
5

Tôi có một chuỗi gồm 3 chuỗi được tạo thành theo cách sao cho tôi có một số nguyên, chỉ định chiều dài byte của mục tiếp theo và sau đó là byte của mục đó và sau đó là byteize của mục tiếp theo, v.v. như thể ai đó đã làm:Chuỗi Ruby # unpack

[a.bytesize, a, b.bytesize, b, c.bytesize, c].pack("na*na*na*") 

Làm cách nào tôi có thể giải nén chính xác một cách đơn giản? Các giải pháp Perl cho vấn đề này là:

my($a, $b, $c) = unpack("(n/a*)3", $data) 

Đối với ruby, mà dường như không hỗ trợ '/' và dấu ngoặc đơn ở giải nén, Tôi đang sử dụng gì đó như:

vals = [] 
3.times do 
    size = data.unpack("n").first 
    data.slice!(0, 2) 
    vals << data.unpack("a#{size}").first 
    data.slice!(0, size) 
end 

Có một dễ dàng hơn cách này?

+1

Trừ khi ai đó tìm thấy giải pháp đơn giản cho điều này, tôi sẽ xem xét yêu cầu tính năng mở rộng giải nén trên trình theo dõi vấn đề của Ruby, có vẻ hữu ích nếu triển khai một số tính năng của Perl – Speed

Trả lời

0

Tôi không thấy cách nào để thực hiện điều này dễ dàng như giải pháp Perl (và đồng ý việc gửi yêu cầu tính năng để thêm vào gói/giải nén của Ruby), nhưng ít nhất tôi có thể cung cấp dung dịch trong dòng ít hơn nếu điều đó giúp:

vals = [] 
until data.empty? 
    vals << data.slice!(0, data.slice!(0,2).unpack('n').first.to_i).unpack("a*").first 
end 
0

Nếu bạn cần bất kỳ xử lý dữ liệu nhị phân nghiêm trọng, có một viên ngọc cho nó: http://bindata.rubyforge.org/ tôi nghĩ rằng bạn nên sử dụng nó, thay vì rèn giải nén vòng chạy un.

Tất nhiên bạn có thể gửi yêu cầu tính năng và đợi nó được triển khai nhưng tôi khuyên bạn nên sử dụng đá quý bindata thay thế, đây là giải pháp IMO mạnh mẽ hơn nhiều.

1

IMHO không dễ dàng như trong PERL, nhưng đây là một số giải pháp tôi có thể đề xuất.

unpacked = [] 
a, b, c = *unpacked << data.slice!(0, data.slice!(0, 2).unpack('S>').first) \ 
      until data.empty?