Converting String, Hex and Fixnum Using Ruby

1.0 Introduction

Software development in the security domains always involve converting from and to hex and binary format. For those new to certain languages, a high learning curve is involved and this translates to increasing the development cost.

This article concentrates in using the ruby language to help new comers shorten the learning curve.

To help us understand this article, we will use the below data:

str = “ABC
D”

Please note that there is a new line character (\n) between C and D. Table 1.0 contains the same variable presented in 4 different formats.

String(Binary) A B C \n D Hex 41 42 43 0A 44 Fixnum(Decimal) 65 66 67 10 68 Binary 01000001 01000010 01000011 00001010 01000100

Table 1.0 Data Presentation Comparison

When we store ‘A’ character into a variable, it needs to be placed in memory. Since our RAM can only store 1 and 0, the ‘A’ character needs to be converted to this binary format. Base on ASCII table (http://www.asciitable.com/) it is agreed that the ‘A’ character should have 01000001 which is equal to 65 in decimal.

From the ASCII table, a new line character will be stored as 00001010 in RAM which is equal to 10(decimal).

Now we are ready for the next phase which is to convert the data into ruby language.

2.1 Converting Hex To BinaryString

First we will look at how to convert hex to binary.

sHex = “4142430A44”
puts [sHex].pack(‘H*’)     ==> “ABC\nD”

pack() is a method  for array object.  Originally sHex is a string, so we need to put it in the block to convert it to array.

Pack method will produce a BinaryString. The ‘H*’ directive will tell ruby that the array element is a Hex string.

There are many directives available (http://ruby-doc.org/core/classes/Array.html#M002222).

2.2 Converting BinaryString To Hex

For converting BinaryString to hex, we should use unpack with H* as the format parameter.

str = “ABC\nD”
str.unpack(‘H*’)  ==> [“4142430a44”]

unpack() will return array which contains a string of the hex format in its first element. To get the  string of hex you can try

str.unpack(‘H*’)[0]    ==> “4142430a44”

2.3 Converting BinaryString To Binary

unpack() can also be used to present data in binary. Use B* as the format parameter as below

str.unpack(‘B*’)[0]  => “0100000101000010010000110000101001000100”

The result is quite long. To understand it, split the string so that each group has 8 numbers. This is because each character consumes 8 bit in memory.

01000001 01000010 01000011 00001010 01000100 A B C \n D

2.4 Converting Hex To Binary

“41”.class is a String. This means our memory will store “00110100” (decimal =52, hex = 34) and “00110001”( decimal = 49, hex = 31).

“41”.hex.class is a FixNum. “41”.hex will tell ruby to read those string as hex, as a result stores “01000001” (decimal = 65, hex = 41) in memory. The two examples will definitely be interpreted differently by a CPU.

To display the same value in binary we can use to_s(2) method from the Fixnum class.

“41”.hex.to_s(2)  ==> “01000001”

The result is a string which contains a binary representative of 0x41.

Value 2 for the parameter means to display the value in base 2. Sending 16 as base will output the same result “41”, as hex is base 16. You can try to pass any integer between 2 and 36 and study the output for further exercise.

2.5 Converting Binary To BinaryString

pack(‘B*’) method from Array class will process the first element of the array and present it in BinaryString.

[“0100000101000010010000110000101001000100”].pack(‘B*’) ==>  “ABC\nD”

3.0 Conclusion

Always remember, that machines do store information in streams of 0 and 1. Since human have limitations in memorizing  long numbers, hex representation is used which can still represent the same value.

Different from both above, string is a stream of character human use for storing information. ASCII table is used to convert information stored in a computer to a format that human can understand

4.0 Reference

1-     http://ruby-doc.org/core/classes/Fixnum.html#M001050
2-     http://ruby-doc.org/core/classes/Array.html#M002222
3-     http://ruby-doc.org/core-1.8.7/classes/ … ml#M000689
4-     http://en.wikipedia.org/wiki/ASCII

Leave a Reply