我试图编写一个函数.unpack('Q')
(unpack to uint64_t),而无需访问unpack方法。
当我手动将字符串转换为二进制文件到uint64时,我得到的结果与.unpack('Q')
不同:
Integer('abcdefgh'.unpack('B*').first, 2) # => 7017280452245743464
'abcdefgh'.unpack('Q').first # => 7523094288207667809
我不明白这里发生了什么。
我也不明白为什么无论输入的大小如何,.unpack('Q')
的输出都是固定的。如果我在' abcdefgh'之后添加了一千个字符。然后解压缩(' Q')它,我仍然只是得到[7523094288207667809]
?
答案 0 :(得分:2)
字节顺序很重要:
Integer('abcdefgh'.
each_char.
flat_map { |c| c.unpack('B*') }.
reverse.
join, 2)
#⇒ 7523094288207667809
'abcdefgh'.unpack('Q*').first
#⇒ 7523094288207667809
您的代码产生错误的结果,因为在转换为二进制文件bytes should be reversed。
之后对于问题的最后一部分,.unpack('Q')
的输出不会因较长的输入字符串而改变的原因是因为格式指定了一个64位值,因此在第一个字符之后的任何字符8被忽略。如果您指定了Q2
格式和16个字符的字符串,那么您需要解码2个值:
> 'abcdefghihjklmno'.unpack('Q2')
=> [7523094288207667809, 8029475498074204265]
并且您再次发现添加其他字符不会改变结果:
> 'abcdefghihjklmnofoofoo'.unpack('Q2')
=> [7523094288207667809, 8029475498074204265]
Q*
格式将返回输入中的64位数的多个值:
> 'abcdefghihjklmnopqrstuvw'.unpack('Q*')
=> [7523094288207667809, 8029475498074204265, 8608196880778817904]
> 'abcdefghihjklmnopqrstuvwxyz'.unpack('Q*')
=> [7523094288207667809, 8029475498074204265, 8608196880778817904]