Wednesday, October 28, 2015

Dealing with Hex in Ruby

Dealing with Hex numbers in Ruby is actually very simple once you understand whats going on underneath.

(Disclaimer: I am no Ruby expert, or even close. The following is simply my understanding of how things work)

Hexidecimal, Decimal, Octal, and Binary are all in the same group. Since they are all different ways of representing the same number, Ruby will show you the decimal representation of the number whenever you deal with things by default.
"A".ord
=> 65
"B".ord
=> 66

(as we talk about things, go ahead and "man ascii" to bring up the tables)
If you check the tables, 65 and 66 are the decimal representations of A and B. This is why I said earlier that Ruby deals with the decimal representation by default.

So how do I convert "A" and "B" to their hexidemical representations? (which is "41" and "42" from the ascii table)? Well it turns out there are several ways, but here are the two i use most:

You can simply use Fixnum's to_s method and tell it the output should be in base 16 (also works for any other base)
"A".ord.to_s(16)
=> "41"
"B".ord.to_s(16)
=> "42"

Or the slightly uglier version by using printf formatting:
"%x" % "A".ord
=> "41"
"%x" % "B".ord
=> "42"

OK well thats all well and good but what if I have the hex/octal/binary/decimal representation of something and i want to convert it to it's ASCII value?

So you remember how i said that ruby tends to deal with the decimal representation of numbers? Ruby gives a handy syntax for you to use when you tell it to deal with a certain number:

Hex: 0x41 = 65 in decimal = "A" in ASCII
Binary: 0b1000001 = decimal 65 = "A" in ASCII
Octal: 0o101 = 65 in decimal = "A" in ASCII
Decimal: 0d65 = 65 in decimal (dur) = "A" in ASCII

So thats how you tell ruby what kind of number your dealing with. Ruby reads whatever you types, convert it to decimal, and then does it's ruby magic on it.

So you can use Fixnum's chr method to convert from the hex/oct/bin/dec value you supply, to it's ASCII representation
0x41
=> 65
0x41.chr
=> "A"

0x42
=> 66
0x42.chr
=> "B"

The nice thing is that since ruby converts everything to decimal, you can do cool things with ranges. You can tell ruby to start at one hex value, increment to an octal value, and output each one as it's ASCII representation:
(0x59..0o143).each do |num|
  puts num.chr
end

Result:
Y
Z
[
\
]
^
_
`
a
b
c

No comments:

Post a Comment