2012-01-23 96 views
2

将数字转换为ASCII字符串的最简洁的Ruby方法是什么?将数值转换为ASCII字符串的Ruby方式是什么?

例如,a = 0x68656c6c6f应该变为a = "hello"

在没有库的普通C中,我会使用一个0xFF掩码,我不断移位。不知何故,我感觉Ruby有这样的更短/更简单的方法。

我正在使用Ruby 1.8.7。

+0

虽然我不喜欢的事实,我需要将其转换为字符串优先(“68656c6c6f”),Array#pack(“H *”)似乎要走 – SirLenz0rlot

+0

'我不喜欢事实,我需要先将其转换为字符串',然后使用'.to_s(16) –

+0

然后我仍然将其转换为字符串:)。我的意思是我希望能够将ruby-ish解决方案转换为ascii字符串,而不必先将其转换为十六进制字符串。 – SirLenz0rlot

回答

2

我认为为所描述的问题编写类C代码没有任何问题。你是在处理低级别的处理,所以它是可以接受的使用低级语法:

n = 0x68656c6c6f 
s = '' 
while n > 0 
    p = n & 0xff 
    n = n >> 8 
    s = p.chr + s 
end 
puts s 

必须有办法让代码感觉更像Ruby的,但是,对于这个问题,我认为这是一个很好的替代。如果你有一个数组,而不是字符序列,它会更容易:

puts [0x68, 0x65, 0x6c, 0x6c, 0x6f].map{|n| n.chr}.reduce(:+) 
+0

感谢您的回答。对我来说,整体移位比使用map + chr + reduce更清晰,因为我知道Ruby非常强大,并且有一种紧凑的方式来做任何事情,我想知道'Ruby-guys'是如何看待这个问题的:-)。现在,我会坚持转变。 – SirLenz0rlot

+1

同时'n,p = n.divmod(256)'将为您节省一行 –

+0

要将字节数组转换为字符串,您还可以这样做:'[0x68,0x65,0x6c,0x6c,0x6f] .pack'c * '' –

5
["68656c6c6f"].pack("H*") #=> "hello" 

看一看的文档为Array,特别是包并解压方法。

+1

你几乎在那里,但'a'应该是一个数字,而不是字符串 –

+1

你是对的,我只是指出他在正确的方向,但是,包和解包方法是为此做的。你对%x的回答很聪明,高调。 –

+0

我用%x评论了答案,它不起作用,因为我期望 – SirLenz0rlot

1
a = "0x68656c6c6f" 
a = a[2..-1] # get rid of the 0x 
a.scan(/../).each { |s| puts s.hex.chr } 
H 
e 
l 
l 
o 
6
["%x" % 0x68656c6c6f].pack("H*") 

更新:另一种疯狂的想法,这可能是矫枉过正,你的情况,但这个作品的权利与前导零。事实上,它只是转移,而是可以进行各种功能像mapinjecteach

class S 
    include Enumerable 

    def initialize(i) 
    @i = i 
    end 

    def each(&block) 
    while @i > 0 
     @i, b = @i.divmod(256) 
     block[b.chr] 
    end 
    end 
end 

S.new(0x0168656c6c6f).inject{ |a, c| c + a } 
+0

我只注意到了一些事情:这只适用于没有前导零的情况! [“%x”%0x0168656c6c6f] .pack(“H *”)不会给出预期的结果(“\ 001hello”) – SirLenz0rlot

+0

我希望我可以再次高兴,很棒的工作!对我而言,整个构造确实有点矫枉过正,我认为这不会增加我的可读性。现在,我会坚持老式的转变 – SirLenz0rlot

0

被用来试试这个

"0x68656c6c6f"[2..-1].gsub(/../) { |val| val.hex.chr } => "hello"