Hex to decimal?

Since nobody else has any Ruby to talk about today… :slight_smile:

My gut feel is that this should be 2 or 3 lines of code but for some
reason I’m missing the trick.

I need a script that converts pairs of hex digits into their decimal
equivalents. Suppose the script accepts a single argument, a string
composed of hex digits, either upper- or lower-case, or both, possibly
with embedded blanks. For the sake of argument let’s say that there’s
always going to be at least 1 pair but never more than, oh, 20 pairs (or
as many as can easily be typed on a command line).

The script should remove any embedded blanks from the argument, then go
through the string left-to-right. For each pair of hex digits, display
the value of the pair as a 3-digit decimal number, separated with a
backslash.

So, for example,

ruby hex2dec.rb “f0 d7e2 28” => \240\215\226\040

Ideas?

On May 17, 2008, at 1:27 PM, ara.t.howard wrote:

string.to_s.strip.split(%r/\s+/).map{|h| “#{ 92.chr }%03d” %
eval(“0x#{h}”)}.join
^^^^
^^^^

oops

a @ http://codeforpeople.com/

Tim H. wrote:

ruby hex2dec.rb “f0 d7e2 28” => \240\215\226\040

def hex2dec hex
[hex.delete(" ")].pack(“H*”).unpack(“C*”).map {|n| “\%03d” % n}.join
end

puts hex2dec(“f0 d7e2 28”) # ==> \240\215\226\040
puts hex2dec(“d00de”) # ==> \208\013\224

On May 17, 2008, at 1:15 PM, Tim H. wrote:

“f0 d7e2 28” => \240\215\226\040

cfp:~ > cat a.rb
def hex2decimal string
string.to_s.split(%r/\s+/).map{|h| “#{ 92.chr }%03d” %
eval(“0x#{h}”)}.join
end

puts hex2decimal(“f0 d7 e2 28”)

cfp:~ > ruby a.rb
\240\215\226\040

a @ http://codeforpeople.com/

Rob B. wrote:

Of course, that’s not a script, but a method. In case this is homework,
that part is left as an exercise. :wink:

Dude! I am so busted.

Tim H. wrote:

Since nobody else has any Ruby to talk about today… :slight_smile:

My gut feel is that this should be 2 or 3 lines of code but for some
reason I’m missing the trick.

I need a script that converts pairs of hex digits into their decimal
equivalents. Suppose the script accepts a single argument, a string
composed of hex digits, either upper- or lower-case, or both, possibly
with embedded blanks. For the sake of argument let’s say that there’s
always going to be at least 1 pair but never more than, oh, 20 pairs (or
as many as can easily be typed on a command line).

The script should remove any embedded blanks from the argument, then go
through the string left-to-right. For each pair of hex digits, display
the value of the pair as a 3-digit decimal number, separated with a
backslash.

So, for example,

ruby hex2dec.rb “f0 d7e2 28” => \240\215\226\040

Ideas?

hex_str = ARGV[0]
hex_str = hex_str.delete(" ")

results = []
stop_index = hex_str.length - 2

0.step(stop_index, 2) do |i|
decimal_num = hex_str[i,2].hex
results << sprintf("%03d", decimal_num)
end

out_str = results.join("\")
puts out_str

$ ruby r1test.rb “F0 d7E2 28”
240\215\226\040

ruby hex2dec.rb “f0 d7e2 28” => \240\215\226\040

“f0 d7e228”.scan(/\w\w/).map{|n| ‘%03d’ % n.to_i(16) }.join(’\’)

Tor Erik

Tim H. wrote:

Ideas?

Thanks to everybody who responded! I learned something from each answer.
(Particularly about when it’s appropriate to use eval!)

On May 17, 2008, at 3:15 PM, Tim H. wrote:

(or
ruby hex2dec.rb “f0 d7e2 28” => \240\215\226\040

Ideas?

A bit different that Ara’s, but this is a nearly method-for-word
translation:

class String
def h2d
[self.gsub(/\s+/,‘’)]. # remove embedded blanks
pack(‘H*’). # convert hex pairs to bytes
split(//). # array of single-byte strings
map{|c| “%03d”%[c[0]]}. # first(only) char as 3
decimal-digits
join(‘\’) # separated by backslash
end
end

Of course, that’s not a script, but a method. In case this is
homework, that part is left as an exercise. :wink:

-Rob

Rob B. http://agileconsultingllc.com
[email protected]