17

I am trying to convert a hex value to a binary value (each bit in the hex string should have an equivalent four bit binary value). I was advised to use this:

num = "0ff" # (say for eg.)
bin = "%0#{num.size*4}b" % num.hex.to_i

This gives me the correct output 000011111111. I am confused with how this works, especially %0#{num.size*4}b. Could someone help me with this?

5 Answers 5

15

You can also do:

num = "0ff"
num.hex.to_s(2).rjust(num.size*4, '0')

You may have already figured out, but, num.size*4 is the number of digits that you want to pad the output up to with 0 because one hexadecimal digit is represented by four (log_2 16 = 4) binary digits.

Sign up to request clarification or add additional context in comments.

1 Comment

Or, more generally, num.to_i(16).to_s(2)
4

You'll find the answer in the documentation of Kernel#sprintf (as pointed out by the docs for String#%):

http://www.ruby-doc.org/core/classes/Kernel.html#M001433

Comments

4

This is the most straightforward solution I found to convert from hexadecimal to binary:

['DEADBEEF'].pack('H*').unpack('B*').first # => "11011110101011011011111011101111"

And from binary to hexadecimal:

['11011110101011011011111011101111'].pack('B*').unpack1('H*') # => "deadbeef"

Here you can find more information:

Comments

0

This doesn't answer your original question, but I would assume that a lot of people coming here are, instead of looking to turn hexadecimal to actual "0s and 1s" binary output, to decode hexadecimal to a byte string representation (in the spirit of such utilities as hex2bin). As such, here is a good method for doing exactly that:

def hex_to_bin(hex)
  # Prepend a '0' for padding if you don't have an even number of chars
  hex = '0' << hex unless (hex.length % 2) == 0
  hex.scan(/[A-Fa-f0-9]{2}/).inject('') { |encoded, byte| encoded << [byte].pack('H2') }
end

Getting back to hex again is much easier:

def bin_to_hex(bin)
  bin.unpack('H*').first
end

Comments

0

Converting the string of hex digits back to binary is just as easy. Take the hex digits two at a time (since each byte can range from 00 to FF), convert the digits to a character, and join them back together.

def hex_to_bin(s) s.scan(/../).map { |x| x.hex.chr }.join end

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.