217

Is there a built in way to convert an integer in Ruby into its hexadecimal equivalent?

Something like the opposite of String#to_i:

"0A".to_i(16) #=>10

Like perhaps:

"0A".hex #=>10

I know how to roll my own, but it's probably more efficient to use a built in Ruby function.

Andrew Marshall
  • 95,083
  • 20
  • 220
  • 214
Matt Haughton
  • 2,919
  • 3
  • 24
  • 30

5 Answers5

344

You can give to_s a base other than 10:

10.to_s(16)  #=> "a"

Note that in ruby 2.4 FixNum and BigNum were unified in the Integer class. If you are using an older ruby check the documentation of FixNum#to_s and BigNum#to_s

Jean
  • 21,329
  • 5
  • 46
  • 64
  • 4
    That's the answer I was looking for but it isn't documented on the linked page str.to_s => str is specified as not accepting parameters and has "Returns the receiver." as the only documentation, but it seems to work – Matt Haughton Sep 17 '08 at 15:39
  • 2
    sorry about that copy paste mistake of course to_s on string doesn't take arguments but on Fixnum it does :) – Jean Sep 17 '08 at 15:46
  • 4
    Ah, I was looking under Integer for a .to_s method and couldn't find one. I'll look under Fixnum next time as well – Matt Haughton Sep 17 '08 at 16:11
  • 1
    Make sure the original number is an instance of Fixnum, Float will throw an exception. – lee Nov 16 '15 at 07:11
  • warning - if you're then splitting the hex number into byte-size segments you'll have to check the length of the result, since it won't be padded with a 0 – Kevin Jul 13 '23 at 01:58
89

How about using %/sprintf:

i = 20
"%x" % i  #=> "14"
Andrew Marshall
  • 95,083
  • 20
  • 220
  • 214
flxkid
  • 1,441
  • 1
  • 13
  • 21
  • 16
    Thanks for showing this, I needed something that would get me a fixed length string prepended with '0'. ex: "%02X" % 10 #=> "0A" – Aaron Hinni Oct 31 '08 at 13:07
  • 42
    And for the other ruby newbies out there: `"#%02x%02x%02x" % [255, 0, 10] #=> "#ff000a"` - took me a bit to figure out how to send several args. – ANeves Mar 22 '11 at 19:08
  • 1
    This is an extremely awesome snippet of Ruby! – OzBandit Nov 09 '12 at 23:40
  • I am new to Ruby, but it seems to me that there is something very subtle going on here. Can someone explain? (+1 BTW) – 681234 Jan 13 '13 at 04:58
  • 4
    @TomD % is a String method that effectively provides a shorthand for sprintf formatting (they make the same internal calls). It's documented in the String class, see http://www.ruby-doc.org/core-1.9.3/String.html#method-i-25 – tardate Feb 13 '13 at 15:22
  • 2
    Less duplication: `[255, 0, 10].map{|x| '%02x'%x}.join` – Rok Kralj Aug 24 '13 at 19:43
  • @AaronHinni: You can also do `10.to_s(16).rjust(2, "0")` – Hubro Oct 29 '13 at 14:47
83

To summarize:

p 10.to_s(16) #=> "a"
p "%x" % 10 #=> "a"
p "%02X" % 10 #=> "0A"
p sprintf("%02X", 10) #=> "0A"
p "#%02X%02X%02X" % [255, 0, 10] #=> "#FF000A"
Lri
  • 26,768
  • 8
  • 84
  • 82
14

Here's another approach:

sprintf("%02x", 10).upcase

see the documentation for sprintf here: http://www.ruby-doc.org/core/classes/Kernel.html#method-i-sprintf

shivam
  • 16,048
  • 3
  • 56
  • 71
Ultrasaurus
  • 3,031
  • 2
  • 33
  • 52
  • 11
    `sprintf("%02X", 10)` will be uppercase because of the upper case X. No need for the upcase method to be called. The specific section of the kernel is this: http://www.ruby-doc.org/core-1.9.3/Kernel.html#method-i-format – BookOfGreg Apr 17 '12 at 21:26
5

Just in case you have a preference for how negative numbers are formatted:

p "%x" % -1   #=> "..f"
p -1.to_s(16) #=> "-1"
tool maker
  • 51
  • 1
  • 1