ruby:将二进制字符串表示为Bignum

时间:2012-04-15 00:08:52

标签: ruby pack bignum unpack

我需要一个任意长度的二进制字符串的数字表示。这个看似微不足道的任务出人意料地变得复杂了。到目前为止我能想出的最好的是

string.unpack('H*')[0].to_i(16)

但是这个操作缺乏可逆性,因为unpack可能会在最高半字节中返回前导零:

['ABC'].pack('H*') == ['0ABC'].pack('H*') # false

现在我需要检查在从整数转换后是否得到偶数个半字节,如果需要则填充零,等等。这一切都很好而且清晰,但我无法相信这一定是如此令人费解。

使用示例进行更新:

s = "\x01\x1D\x9A".force_encoding 'binary' # "\x01\x1D\x9A"
s.unpack('H*') # ["011d9a"]
s.unpack('H*')[0].to_i(16) # 73114

现在让我们解码:

s.unpack('H*')[0].to_i(16).to_s(16) # "11d9a" — notice that leading zero is gone
[s.unpack('H*')[0].to_i(16).to_s(16)].pack('H*') # "\x11\xD9\xA0"
[s.unpack('H*')[0].to_i(16).to_s(16)].pack('H*') == s # false, obviously

换句话说,我们无法解码到我们开始使用的相同值。

1 个答案:

答案 0 :(得分:0)

不幸的是,我对Ruby没有任何了解,但有一个想法可以检查......

可能是.to_s(16)方法转换为具有不同默认编码的字符串,当你在.pack('H *')之后进行字符串比较时,这可能是重要的吗? 可能这会工作: [s.unpack('H *')[0] .to_i(16).to_s(16)]。pack('H *')。force_encoding'binary'== s

否则,很难想象带有前导零的半字节如何转换为字符串字节,该字节字节与相同的字符串字节不同,但是从十六进制半字节转换而不是零。