Как получить следующие 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
Ты не умеешь читать IO
s побитно, вы должны прочитать целые числа байтов и извлечь биты из них, используя маскировку. Почти все протоколы разрабатываются с учетом этого и позволяют считывать n байтов, а затем разбивать эти n байтов на поля.