Неожиданные результаты распаковки с битовыми строками
почему это, когда я открываю irb и запускаюputs 'A'.unpack("B8")
Я получаю 01000001
но когда я запускаюputs 'A'.unpack("B4B4")
Я только 0100
, а не [0100,0001]
?
является ли разрешение распаковки только полным байтом? Не меньше?
1 ответов
давайте сделаем несколько тестов, чтобы понять поведение:
> 'A'.unpack('B8')
=> ["01000001"]
он возвращает 8 наиболее значимых битов (MSBs) char 'A'
> 'A'.unpack('B4')
=> ["0100"]
он возвращает 4 MSBs char 'A'
> 'A'.unpack('B16')
=> ["01000001"]
он возвращает 16 MSBs char 'A'
, но так как есть только 8, мы получаем 8 MSBs
> 'AB'.unpack('B16')
=> ["0100000101000010"]
он возвращает 16 MSBs последовательности символов 'AB'
(конец 8 бит 01000010
соответствует 'B'
)
> 'AB'.unpack('B10')
=> ["0100000101"]
он возвращает 10 MSBs последовательности символов 'AB'
, т. е. 8 MSBs 'A'
и 2 MSBs 'B'
> 'ABC'.unpack('B*')
=> ["010000010100001001000011"]
он возвращает все MSBs последовательности символов 'ABC'
, (конец 8 бит 01000011
соответствует 'C'
)
> 'AB'.unpack('B8B8')
=> ["01000001", "01000010"]
возвращает следующий массив:
- первым элементом является 8 MSBs char
'A'
- второй элемент 8 MSBs чар
'B'
_
> 'AB'.unpack('B8B7')
=> ["01000001", "0100001"]
возвращает следующий массив:
- первым элементом является 8 MSBs char
'A'
- второй элемент-это 7 MSBs символа
'B'
_
> 'AB'.unpack('B4B8')
=> ["0100", "01000010"]
возвращает следующий массив:
- первым элементом является 4 MSBs char
'A'
- второй элемент 8 MSBs чар
'B'
_
> 'AB'.unpack('B16B8')
=> ["0100000101000010", ""]
возвращает следующий массив:
- первым элементом является 16 MSBs последовательности символов
'AB'
- второй элемент пуст, так как символы уже были потреблены
_
> 'AB'.unpack('B*B8')
=> ["0100000101000010", ""]
он дает вам тот же результат и потребляет всю строку.
> 'AB'.unpack('B9B8')
=> ["010000010", ""]
он возвращает следующее массив:
- первым элементом является 9 MSBs последовательности символов
'AB'
- второй элемент пуст, так как символы уже были потреблены
в заключение
директива BN
над строкой будет потреблять не более первого ((N-1) / 8) + 1
символы строки. Если в строке все еще есть символы, и у вас есть вторая директива BM
, вы будете потреблять не более следующего ((M-1) / 8) + 1
символы строки. И так далее для всех следующих директив. Если вы используете директиву B*
, он будет потреблять все символы и возвращает последовательность их соответствующих MSBs.
например:
'ABCDEFG'.unpack('B17B*B8')
он должен вернуть нам:
- 17 MSBs последовательности
ABC
- все MSBs последовательности
DEFG
- пустая битовая строка
> 'ABCDEFG'.unpack('B17B*B8')
=> ["01000001010000100", "01000100010001010100011001000111", ""]
и действительно 'A'.unpack('B4B4')
возвращает массив ["0100", ""]
как первая директива потребляет char A
.