【问题标题】:How to print numbers in hex with leading zero如何打印带有前导零的十六进制数字
【发布时间】:2014-10-28 10:09:03
【问题描述】:

有没有更好的方法以十六进制显示数字,前导0?我试过了:

i.to_s(16)

但是

2.to_s(16) #=> "2" 

我期望"02"。我试过打印格式:

"%02x" % i

适用于2,但是

"%02x" % 256 #=> "100"

我想要"0100"。所以我想出了这个:

class Integer
  def to_hex_string
    ("%0x" % self).size % 2 == 0 ? "%0x" % self : "%0#{("%0x" % self).size+1}x" % self
  end
end

有效:

2.to_hex_string #=> "02"
256.to_hex_string #=> "0100"

它也适用于 Bignumber 类,但看起来很奇怪,这么简单的请求需要这样的技巧。有更好的主意吗?

【问题讨论】:

  • 如果您只想在数字前面加一个零,请尝试"0#{i.to_s(16)}""0%x" % i。但这通常表示一个八进制数。常见的十六进制前缀是0x,可以使用"%#x" % i打印。
  • 感谢您的评论,但似乎 to_s(16) 被 BigNumber 窃听

标签: ruby hex hexdump leading-zero


【解决方案1】:

是的,它出错了:

让我们试试这个:

class Integer
  def to_hex_string
     "0#{to_s(16)}"
  end
end

class BigNumber
  def to_hex_string
    "0#{to_s(16)}"
  end
end

class String
  def to_hex_string
    self.unpack('H*').first
  end

  def to_bytes_string
    unless self.size % 2 == 0
      raise "Can't translate a string unless it has an even number of digits"
    end
    raise "Can't translate non-hex characters" if self =~ /[^0-9A-Fa-f]/
    [self].pack('H*')
  end

  def to_bignum
    self.bytes.inject { |a,b| (a << 8) + b }
  end
end

p a="ff"*192 # => "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"

p bytestring=a.to_bytes_string # => "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"

p bytestring.to_hex_string # => "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"

p biga=a.to_bytes_string.to_bignum # => 2410312426921032588580116606028314112912093247945688951359675039065257391591803200669085024107346049663448766280888004787862416978794958324969612987890774651455213339381625224770782077917681499676845543137387820057597345857904599109461387122099507964997815641342300677629473355281617428411794163967785870370368969109221591943054232011562758450080579587850900993714892283476646631181515063804873375182260506246992837898705971012525843324401232986857004760339316735

BUG就在这里:

p biga.to_hex_string # => "0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"

这个0是哪里来的???

更奇怪的是我的复杂解决方案正在起作用:

p ("%0x" % biga).size % 2 == 0 ? "%0x" % biga : "%0#{("%0x" % biga).size+1}x" % biga # => "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"

可能是“0#{to_s(16)}”中的错误?

【讨论】:

    【解决方案2】:

    对于 2 位十六进制值,此方法有效:

    def to_hex(int)
      int < 16 ? '0' + int.to_s(16) : int.to_s(16)
    end
    

    【讨论】:

      【解决方案3】:

      当我试图解决这个问题时,这是 Google 上的第一个热门话题。我必须找到其他几个帖子来完成我的解决方案,但我认为这很干净。

      class Fixnum
        def to_hex(bits)
          rjust = (bits/4 + (bits.modulo(4)==0 ? 0 : 1))
          "0x" + self.to_s(16).rjust(rjust, "0")
        end
      end
      

      【讨论】:

        【解决方案4】:

        你把这种方法弄得太复杂了。如果你想打印一个带有前导零的十六进制整数,那么它只是

        class Integer
          def to_hex_string
            "0#{to_s(16)}"
          end
        end
        
        2.to_hex_string   # => 02
        256.to_hex_string # => 0100
        

        【讨论】:

        • 这样肯定容易多了!谢谢!
        • 但它似乎是 bignumber 的错误。如果您尝试以“ff”*192 为例,如果将错误转换为 bignum 并返回到 hex
        • 这个答案是错误的恕我直言:它总是在前面放一个 0。我认为 OP 在 2.to_hex_string = 02 的情况下希望前面有一个 0,但 200.to_hex_string 可能应该返回“c8”而不是“0c8”,即前导 0 应该只添加在奇数字符串长度上。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-08-05
        • 2013-05-10
        • 1970-01-01
        • 1970-01-01
        • 2023-03-25
        • 1970-01-01
        • 2019-01-29
        相关资源
        最近更新 更多