我有一个情况需要在Ruby中将二进制值转换为十六进制。我的情况如下:
当bin = "0000111"
时,我的输出应该是:hex = "07"
。
当bin = "010001111"
时,我的输出应该是:hex = "08f"
。
有人能帮助我如何做到这一点吗?谢谢提前。
如何尝试:
>> "0x%02x" % "0000111".to_i(2) #=> "0x07"
>> "0x%02x" % "010001111".to_i(2) #=> "0x8f"
编辑:如果你不想要输出为 0x..
而只想要 0..
,那么在格式化字符串中省略第一个 x
。
注意: 本翻译中的 "leave out" 翻译为 "省略",意为在格式化字符串中不包含该字符。
def bin_to_hex(s)
s.each_byte.map { |b| b.to_s(16).rjust(2,'0') }.join
end
我在这里找到了它(包括零填充修改):
http://anthonylewis.com/2011/02/09/to-hex-and-back-with-ruby/
'1111'.each_byte.map { |b| b.to_s(16) }.join => "31313131"
(而我想要的是 "f"
或类似的东西)。 - Djunzu'1111'
有四个字节,每个字节的值为49(即ASCII值)。十进制中的49在十六进制中是31。你没有一个像问题所说的那样的“二进制”值。你有一个包含ASCII字符'1'
和'0'
的字符串。 - RyanString#to_i
和Integer#to_s
都可以接受一个可选的整数参数,指定基数。因此,您可以使用基数2将二进制字符串转换为整数,然后使用基数16将该整数转换回字符串。
String#%
(又称为sprintf
)而不是 to_s
来适当地格式化数字,使用 %02x
将数字格式化为用0填充的两位十六进制数。但是如果您想要除16(或者使用 d
而不是 x
的10)以外的其他基数,则无法使用 %
选择任意基数。或者,您可以使用 to_s
后跟 String#rjust
,它可以与任意基数和填充字符一起使用。 - sepp2kunpack
方法,将目标指向十六进制。def bin_to_hex(binary_string)
binary_string.unpack('H*').first
end
参考:https://apidock.com/ruby/String/unpack
我认为这个方案比上面列出的解决方案更加简洁。
# if you don't want the output to be 0x.. but just 0.. leave out the first x in the format string.
def self.bin_to_hex(string)
"0x%02x" % "#{string}".to_i(2)
end
然后像这样使用该方法
string = "00011110"
puts bin_to_hex(string)
=> 0x1e
请记住这些仍然是ASCII表示,如果您想将其编码并以HEX字节形式发送(通过UDP或低级协议发送),只需执行以下操作:
value = self.bin_to_hex(value)
bytes = [value]
bytes.pack('H*' * bytes.size)