我需要一个任意长度的二进制字符串的数字表示。这个看似微不足道的任务出人意料地变得复杂了。到目前为止我能想出的最好的是
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
换句话说,我们无法解码到我们开始使用的相同值。
答案 0 :(得分:0)
不幸的是,我对Ruby没有任何了解,但有一个想法可以检查......
可能是.to_s(16)方法转换为具有不同默认编码的字符串,当你在.pack('H *')之后进行字符串比较时,这可能是重要的吗? 可能这会工作: [s.unpack('H *')[0] .to_i(16).to_s(16)]。pack('H *')。force_encoding'binary'== s
否则,很难想象带有前导零的半字节如何转换为字符串字节,该字节字节与相同的字符串字节不同,但是从十六进制半字节转换而不是零。