6

为什么当我打开 irb 并运行时
puts 'A'.unpack("B8")
我得到01000001但当我运行时
puts 'A'.unpack("B4B4")
我只得到0100而不是[0100,0001]

unpack 的分辨率是否只有一个完整的字节?一点也不少?

4

1 回答 1

5

让我们做一些测试来理解行为:

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

它返回 char 的 8 个最高有效位 (MSB)'A'

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

它返回 char 的 4 个 MSB'A'

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

它返回 char 的 16 个 MSB 'A',但由于只有 8 个,我们得到了 8 个 MSB

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

它返回字符序列的 16 个 MSB 'AB'(最后 8 位01000010对应于'B'

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

它返回 chars 序列的 10 个 MSB 'AB',即 8 个 MSB'A'和 2 个 MSB'B'

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

它返回 chars 序列的所有 MSB 'ABC',(最后 8 位01000011对应'C'

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

它返回以下数组:

  • 第一个元素是 char 的 8 个 MSB'A'
  • 第二个元素是 char 的 8 个 MSB'B'

_

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

它返回以下数组:

  • 第一个元素是 char 的 8 个 MSB'A'
  • 第二个元素是 char 的 7 个 MSB'B'

_

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

它返回以下数组:

  • 第一个元素是 char 的 4 个 MSB'A'
  • 第二个元素是 char 的 8 个 MSB'B'

_

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

它返回以下数组:

  • 第一个元素是字符序列的 16 个 MSB'AB'
  • 第二个元素为空,因为字符已被消耗

_

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

它为您提供相同的结果,并消耗所有字符串。

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

它返回以下数组:

  • 第一个元素是字符序列的 9 个 MSB'AB'
  • 第二个元素为空,因为字符已被消耗

作为结论,

对字符串的指令BN最多会消耗字符串的第一个((N-1) / 8) + 1字符。如果字符串中仍有字符,并且您有第二个指令BM,则最多会消耗((M-1) / 8) + 1字符串的下一个字符。对于所有下一个指令,依此类推。如果使用指令B*,它将消耗所有字符,并返回其对应 MSB 的序列。

例如:

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

它应该返回我们:

  • 序列的 17 个 MSBABC
  • 序列的所有 MSBDEFG
  • 一个空的位串

让我们检查:

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

并且确实'A'.unpack('B4B4')返回数组["0100", ""],因为第一个指令使用 char A

于 2013-04-24T13:03:27.777 回答