Subscribe to Stuck in an Infiniteloop        RSS Feed
-----

Working with Binary Data in Ruby

Icon Leave Comment
Ruby is fun. Ruby is sexy. But Ruby doesn't do underlying bytes as nice as I'd like. But Knowles, whatever do you mean?

Consider the following, I have a file with contents:

Quote

DEADCAFE


If I tell you nothing else about the file, what can you infer? Well it's probably hex, but maybe it's ascii. If you read this file in Ruby and print it out what do you get?

contents = File.open("test_1").read
puts contents 



Quote

DEADCAFE


Alright that is great, but what is it? Ruby provides some built in functionality to "convert" things to and fro, but it's default character set is ASCII. That means for each character in the above, that is one byte.

Why is this important? If I wanted the above to be the hex representation of something else, I am now dead in the water. DE is one byte, but Ruby thinks each letter is a byte. What is a poor programmer to do? One such option is to tell it to group each two characters and give you the binary/integer value:

hex_bin = contents.scan(/../).map { |pair| pair.hex.chr}.join
puts hex_bin
puts hex_bin.bytes



Quote

*unprintable binary*
222 //DE
173 //AD
202 //CA
254 //FE


Whew, that's better. We have taken our 8 ascii bytes and converted them into 4 actual bytes of binary data we can do something with.

hex - "Treats leading characters from str as a string of hexadecimal digits "
chr - "Returns a one-character string at the beginning of the string."

Without the chr we would concatenate all together: "222173202254" and there would be 12 bytes in the following call, one for each of the numbers is the preceding string. This would be bad, since we want to get the four actual bytes in the resultant buffer.

There is another option to do some of this as well, and it can be found in the pack/unpack methods of Array and String respectively.

Let's take those for a spin:

Array's pack

other_hex_bin = ["DEADCAFE"].pack('H*')
puts other_hex_bin.bytes



Quote

222
173
202
254


and String's unpack

buf = other_hex_bin.unpack('H*')
puts buf



Quote

deadcafe


Hooray! The unpack/pack pages read like printf/scanf if you're familiar with the C functions. Some of the examples the Ruby pages give make my eyes roll back into my head, so proceed with caution.

----------------------

Always know what your input is going to be and how your language of choice affects it and you will be a very happy programmer.

0 Comments On This Entry

 

May 2019

S M T W T F S
   1234
567891011
12131415161718
1920 21 22232425
262728293031 

Tags

    Recent Entries

    Recent Comments

    Search My Blog

    0 user(s) viewing

    0 Guests
    0 member(s)
    0 anonymous member(s)