【问题标题】:ruby: representing binary string as Bignumruby:将二进制字符串表示为 Bignum
【发布时间】:2012-04-15 00:08:52
【问题描述】:

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

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

换句话说,我们未能解码到与开始时相同的值。

【问题讨论】:

  • 给出示例输入和预期输出。您的帖子仅使用您编写的代码描述性不够。
  • 刚才有什么问题:string.to_i(16)?
  • string.to_(16) 转换一串十六进制数字,而不是任意位串。

标签: ruby pack bignum unpack


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-12
    • 1970-01-01
    • 1970-01-01
    • 2011-08-03
    • 2017-10-09
    • 2020-08-02
    • 1970-01-01
    • 2016-09-21
    相关资源
    最近更新 更多