2013-04-24 13 views
6

Perché è che quando apro irb e corro
puts 'A'.unpack("B8")
ottengo 01000001 ma quando corro
puts 'A'.unpack("B4B4")
ho solo 0100 e non [0100,0001]?risultati decomprimere imprevisti con stringhe di bit

La risoluzione di decomprimere solo un byte completo? Nientemeno?

+1

I documenti Ruby sono un po 'vaghi. Tuttavia, 'pack' e' unpack' di Ruby sono praticamente copie diritte da Perl e [Perl's 'B'] (http://perldoc.perl.org/functions/pack.html) dice" Ordine bit discendente * all'interno di ogni byte * "(sottolineatura mia). –

risposta

5

Facciamo alcuni test per capire il comportamento:

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

restituisce il 8 La maggior parte dei bit significativi (MSB) di char 'A'

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

Esso restituisce i 4 MSB di char 'A'

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

Restituisce i 16 MSB di char 'A', ma c'è solo 8 otteniamo gli 8 bit più significativi

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

restituisce i 16 bit MSB della sequenza di caratteri 'AB' (i terminali 8 bit 01000010 corrisponde 'B')

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

Riporta i 10 MSB della sequenza di caratteri 'AB', ad esgli 8 bit più significativi di 'A' e le 2 MSB del 'B'

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

restituisce tutto il MSB della sequenza di caratteri 'ABC', (fine 8 bit 01000011 corrisponda a 'C')

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

restituisce il seguente matrice:

  • il primo elemento è il 8 MSB del char 'A'
  • il secondo elemento è 8 bit più significativi del char 'B'

_

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

Riporta la seguente matrice:

  • il primo elemento è il 8 MSB del char 'A'
  • il secondo elemento sono i 7 MSB del carattere 'B'

_

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

Riporta la seguente matrice:

  • il primo elemento è il 4 MSB del char 'A'
  • il secondo elemento è 8 bit più significativi del char 'B'

_

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

Riporta la seguente matrice:

  • il primo elemento è il 16 MSB della sequenza di caratteri 'AB'
  • il secondo elemento è vuota come i caratteri sono già stati consumati

_

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

Ti dà lo stesso risultato e consuma tutta la stringa.

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

Riporta la seguente matrice:

  • il primo elemento è il 9 MSB della sequenza di caratteri 'AB'
  • il secondo elemento è vuota come i caratteri sono già stati consumati

Come conclusione,

la direttiva BN su una stringa consumerà al massimo i primi caratteri ((N-1)/8) + 1 della stringa. Se nella stringa sono ancora presenti caratteri e si dispone di una seconda direttiva BM, si consumano al massimo i successivi caratteri ((M-1)/8) + 1 della stringa. E così via per tutte le prossime direttive. Se si utilizza la direttiva B*, verranno utilizzati tutti i caratteri e verrà restituita la sequenza dei rispettivi MSB corrispondenti.

Ad esempio:

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

Dovrebbe ci restituisce:

  • i 17 bit MSB della sequenza ABC
  • tutto il MSB della sequenza DEFG
  • un bitstring vuoto
assegno

Let:

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

E infatti 'A'.unpack('B4B4') restituisce la matrice ["0100", ""] come la prima direttiva consuma il char A.

+0

Wow! Grazie per il lavoro alle gambe! Ora capisco. Mi aspettavo che disimballasse letteralmente a poco a poco e consumando solo metà del personaggio se richiesto. Non ho considerato la direttiva consumare l'intero carattere nella stringa. – Justin