2013-04-24 32 views
6

Tại sao khi tôi mở ra IRB và tôi chạy
puts 'A'.unpack("B8")
tôi nhận được 01000001 nhưng khi tôi chạy
puts 'A'.unpack("B4B4")
tôi chỉ nhận được 0100 và không [0100,0001]?kết quả giải nén bất ngờ với chuỗi bit

Độ phân giải của giải nén chỉ là một byte đầy đủ? Không có gì ít hơn?

+1

Tài liệu Ruby có chút mơ hồ. Tuy nhiên, 'pack' và' unpack' của Ruby là các bản sao khá thẳng từ Perl và [Perl's 'B'] (http://perldoc.perl.org/functions/pack.html) nói" thứ tự bit giảm dần * bên trong mỗi byte * "(nhấn mạnh mỏ). –

Trả lời

5

Hãy làm một số xét nghiệm để hiểu được hành vi:

> 'A'.unpack('B8') 
=> ["01000001"] 

Nó trả về 8 Hầu hết ý nghĩa Bits (MSB) của char 'A'

> 'A'.unpack('B4') 
=> ["0100"] 

Nó trả về 4 MSB của char 'A'

> 'A'.unpack('B16') 
=> ["01000001"] 

Nó trả về 16 MSB của char 'A', nhưng khi chỉ có 8 chúng tôi nhận được 8 MSB

> 'AB'.unpack('B16') 
=> ["0100000101000010"] 

Nó trả về 16 MSB của chuỗi các ký tự 'AB' (cuối 8 Bits 01000010 tương ứng với 'B')

> 'AB'.unpack('B10') 
=> ["0100000101"] 

Nó trả về 10 MSB của chuỗi ký tự 'AB', tức là8 MSB của 'A' và 2 MSB của 'B'

> 'ABC'.unpack('B*') 
=> ["010000010100001001000011"] 

Nó trả về tất cả các MSB của chuỗi các ký tự 'ABC', (cuối 8 Bits 01000011 tương ứng với 'C')

> 'AB'.unpack('B8B8') 
=> ["01000001", "01000010"] 

Nó trả về mảng sau:

  • phần tử đầu tiên là 8 MSB của char 'A'
  • yếu tố thứ hai là 8 MSB của char 'B'

_

> 'AB'.unpack('B8B7') 
=> ["01000001", "0100001"] 

Nó trả về mảng sau:

  • các yếu tố đầu tiên là 8 MSB của char 'A'
  • yếu tố thứ hai là 7 MSB của char 'B'

_

> 'AB'.unpack('B4B8') 
=> ["0100", "01000010"] 

Nó trả về mảng sau:

  • các yếu tố đầu tiên là 4 MSB của char 'A'
  • yếu tố thứ hai là 8 MSB của char 'B'

_

> 'AB'.unpack('B16B8') 
=> ["0100000101000010", ""] 

Nó trả về mảng sau:

  • các yếu tố đầu tiên là 16 MSB của chuỗi các ký tự 'AB'
  • yếu tố thứ hai là trống rỗng như các ký tự đã được tiêu thụ

_

> 'AB'.unpack('B*B8') 
=> ["0100000101000010", ""] 

Nó mang lại cho bạn kết quả tương tự, và tiêu thụ tất cả các chuỗi.

> 'AB'.unpack('B9B8') 
=> ["010000010", ""] 

Nó trả về mảng sau:

  • các yếu tố đầu tiên là 9 MSB của chuỗi các ký tự 'AB'
  • yếu tố thứ hai là trống rỗng như các ký tự đã được tiêu thụ

Kết luận,

chỉ thị BN trên Chuỗi sẽ tiêu thụ tối đa ((N-1)/8) + 1 ký tự đầu tiên của Chuỗi. Nếu vẫn còn ký tự trong chuỗi và bạn có chỉ thị thứ hai BM, bạn sẽ tiêu thụ tối đa ((M-1)/8) + 1 ký tự tiếp theo của Chuỗi. Và cứ tiếp tục cho tất cả các chỉ thị tiếp theo. Nếu bạn sử dụng chỉ thị B*, nó sẽ tiêu thụ tất cả các ký tự và trả về chuỗi các MSB tương ứng của chúng.

Ví dụ:

'ABCDEFG'.unpack('B17B*B8') 

Nó nên trả về chúng tôi:

  • 17 MSB của dãy ABC
  • tất cả các MSB của dãy DEFG
  • một bitstring trống
.210

Hãy kiểm tra:

> 'ABCDEFG'.unpack('B17B*B8') 
=> ["01000001010000100", "01000100010001010100011001000111", ""] 

Và quả thực 'A'.unpack('B4B4') trả về mảng ["0100", ""] như chỉ thị đầu tiên tiêu thụ các char A.

+0

Wow! Cảm ơn vì công việc chân! Giờ thì tôi đã hiểu. Tôi đã mong đợi nó để giải nén theo nghĩa đen từng chút một và chỉ tiêu thụ một nửa nhân vật nếu được yêu cầu. Tôi đã không xem xét chỉ thị tiêu thụ toàn bộ nhân vật trong chuỗi. – Justin

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