Len
Len

Reputation: 2145

What is the Ruby way to convert a value to an ASCII string?

What is the cleanest Ruby way to convert a number to an ASCII string?

for example, a = 0x68656c6c6f should become a = "hello".

In normal C without libraries, I would use a 0xFF mask which I kept shifting. Somehow I've the feeling Ruby has shorter/less explicit ways to do this.

I'm using Ruby 1.8.7.

Upvotes: 3

Views: 4839

Answers (5)

Rahul Patel
Rahul Patel

Reputation: 1424

Try this

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

Upvotes: 0

Victor Moroz
Victor Moroz

Reputation: 9225

["%x" % 0x68656c6c6f].pack("H*")

Update: Another crazy idea, which is probably overkill in your case, but this one works right with leading zeros. In fact it's just shift, but can be used with various function like map, inject, each etc.

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 }

Upvotes: 6

siame
siame

Reputation: 8657

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

Upvotes: 1

Tom De Leu
Tom De Leu

Reputation: 8274

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

Have a look at the docs for Array, specifically the pack and unpack methods.

Upvotes: 5

Adiel Mittmann
Adiel Mittmann

Reputation: 1764

I think that there's nothing wrong with writing C-like code for the problem that you described. You are dealing with low-level processing, so it's acceptable to use low-level syntax:

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

There must be ways to make the code feel more like Ruby, but, for this problem, I think it's a good alternative. If you had the sequence of characters in an array instead, it would be easier:

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

Upvotes: 3

Related Questions