如何使用Crystal获取下n位

时间:2017-05-03 05:06:09

标签: crystal-lang

我正在尝试从mp3文件中读取ID3v2信息。部分原因是阅读标志。 f.gets n获取n个字节,但我需要n位。

3 个答案:

答案 0 :(得分:2)

基于bit masking的以下方法似乎对我有用:

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

在新行(或ctrl-d for Windows)上输入“abc”后跟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

我已经打印了结果,但您可以随意使用这些位。

借鉴Julien Portalier的回应和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

答案 1 :(得分:2)

读取单个字节,然后使用byte.bit(7)向下byte.bit(0)检查是否设置了一个位。这比bitmasks更好,更明确。

答案 2 :(得分:1)

您无法逐位读取IO,您必须读取整个字节数并使用屏蔽从中提取位。几乎所有协议的设计都考虑到了这一点,并允许您读取n个字节,然后将这n个字节拆分为字段。