Как получить следующие n бит с помощью Crystal

Я пытаюсь прочитать информацию ID3v2 из mp3 файла. Часть этого - чтение флагов. f.gets n получает меня n байты, но мне нужно n биты.

3 ответа

Прочитайте один байт, затем используйте byte.bit(7) до byte.bit(0) проверить, установлен ли бит. Это лучше и понятнее, чем битовые маски.

Мне кажется, что следующий подход, основанный на битовой маскировке, работает нормально:

while input = gets 1 # get one char of input
  x = input.bytes[0] # convert it to numeric byte value
  # In the following, (7 - i) picks bits from left to right...
  8.times { |i| print ((x >> (7 - i)) & 1) } # shift, bit mask, and print bit
  puts # each byte on a separate line
end

введите "abc" с последующим ctrl-d на новой строке (или ctrl-z для винды) выдает

01100001  # a is ascii 97
01100010  # b is ascii 98
01100011  # c is ascii 99
00001010  # line feed

без описательных комментариев, очевидно.

Это также работает для ввода без ascii, такого как "фыв":

11010001
10000100
11010001
10001011
11010000
10110010
00001010

Я напечатал результаты, но вы можете использовать биты так, как вам нравится.


Опираясь на ответ Жюльена Порталье и комментарий от RX14, яснее будет следующее:

while byte = STDIN.read_byte # get one byte of input at a time
  7.downto(0) { |i| print byte.bit(i) } # extract bits left-to-right
  puts # put a newline after each byte
end

Ты не умеешь читать IOs побитно, вы должны прочитать целые числа байтов и извлечь биты из них, используя маскировку. Почти все протоколы разрабатываются с учетом этого и позволяют считывать n байтов, а затем разбивать эти n байтов на поля.

Другие вопросы по тегам