Authors Top

If you have a few years of experience in the Linux ecosystem, and you’re interested in sharing that experience with the community, have a look at our Contribution Guidelines.

1. Overview

Often we need to deal with binary data. For instance, data from the network or the header of an image file are in binary format. If we print that out to the stdout, it shows some garbled characters, which are very difficult to understand.

In an earlier tutorial, we’ve seen how to create a hex dump of a file.

In this tutorial, we’ll see different ways to convert binary data to hexadecimal format.

2. Sampling Binary Data

Image files are a good source for binary data. For instance, the image metadata is stored in the file header in a binary format.

Let’s sample the contents of an image file header:

$ head -c 8 Image1.png 
�PNG

Here, we’ve used the head command to read the first eight bytes from the file. And we can see that it didn’t print the data properly.

However, in Linux, we have various tools to convert the binary data to hexadecimal for easier reading. Let’s look at some of them.

3. Using the hexdump Command

The hexdump command is the first command that comes to mind when we convert binary data to hexadecimal format. It helps us to print the result in different ways.

Let’s look at an example:

$ head -c 8 ~/Pictures/Image1.png | hexdump 
0000000 5089 474e 0a0d 0a1a                    
0000008

After extracting the bytes from an image file, we’ve piped it to the hexdump command. And it printed the hexadecimal values correctly. We’ve used the hexdump command without any options.

3.1. Print ASCII Values

Typically, we would like to see the ASCII value of each byte. Having that side by side, we’ll be able to recognize the contents easily.

Let’s take a look at how we can do this:

$ head -c 8 ~/Pictures/Image1.png | hexdump -C
00000000  89 50 4e 47 0d 0a 1a 0a                           |.PNG....|
00000008

We’ve used the -C option to print the ASCII values. From the ASCII values, we could quickly identify it as a PNG file.

3.2. Formatting Output

The hexdump command provides a -e option, which can be used to format the output in different ways as we need.

Firstly, let’s start by printing just the hexadecimal values:

$ head -c 8 ~/Pictures/Image1.png | hexdump -e '8/1 "%02X " "\n"' 
89 50 4E 47 0D 0A 1A 0A

Here, we passed a format string along with the -e option.

Let’s look at the different parameters in it:

  • 8/1: prints 8 bytes in a line and 1 byte at a time
  • ‘%02X ‘: prints in hexadecimal format with two digits having leading zeros
  • \n: prints a newline as a separator in the end

Secondly, let’s add an address field for this:

$ head -c 8 ~/Pictures/Image1.png | hexdump -e '"%04_ax -> " 4/1 "%02X " "\n"' 
0000 -> 89 50 4E 47
0004 -> 0D 0A 1A 0A

We’ve used the _ax option to add the address field. Prefixing %04 to it, we’ve specified the width of that field to be 4 digits with leading zeros. Finally, we’ve used the -> symbol as a separator.

Finally, let’s check how can we add the ASCII format:

$ head -c 8 ~/Pictures/Image1.png | hexdump -e '"%04_ax -> " 4/1 "%02X "' -e '"   |" 4/1 " %_p" " |\n"'
0000 -> 89 50 4E 47   | . P N G |
0004 -> 0D 0A 1A 0A   | . . . . |

Here, we’ve used a second -e option to print the ASCII format. We’ve used the _p option to print the ASCII values. Also, we used the | symbol as the separator.

4. Using the xxd Command

The xxd command creates a hex dump from any binary data. It also helps to format the output in the way we want.

Let’s take a look:

$ head -c 8 Image1.png | xxd 
00000000: 8950 4e47 0d0a 1a0a                      .PNG....

Here, we read binary data from the image file. Then that is passed to the xxd command. We’ve used the xxd without any options. And it has printed the binary data in hex and ASCII format.

4.1. Formatting the Output

Default output may not be the one we always need.

So, let’s look at some of the formatting options. -g 1 is used to group by 1 byte. We can also use -c 8 to have 8 columns per line:

$ head -c 8 ~/Pictures/Image1.png | xxd -g 1 -c 8
00000000: 89 50 4e 47 0d 0a 1a 0a  .PNG....

Finally, with -ps, we get plain hex values:

$ head -c 8 ~/Pictures/Image1.png | xxd -ps
89504e470d0a1a0a

And -i is used to printing in C, including file style. It is very helpful to initialize variables in C with binary data:

$ head -c 8 ~/Pictures/Image1.png | xxd -i
  0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a

5. Using the od Command

Next, we’ll look at the od command, typically used for converting between different formats. By default, it dumps the results in octal format. However, there are options to print the result in hexadecimal format.

Let’s take a look at that:

$ head -c 8 ~/Pictures/Image1.png | od -x
0000000 5089 474e 0a0d 0a1a
0000010

Here, after reading the file, we’ve used the od command with the -x option. As a result, it prints the data in hexadecimal format.

By default, this option will print 2 bytes in width. But, if we want to print one byte at a time, we can use the -t option.

Let’s check that:

$ head -c 8 ~/Pictures/Image1.png | od -t x1
0000000 89 50 4e 47 0d 0a 1a 0a
0000010

-t x1 formats the output in hexadecimal form with 1 byte at a time.

6. Conclusion

In this tutorial, we’ve seen different ways of converting binary data into hexadecimal format. With these commands, we can confidently deal with binary data.

Authors Bottom

If you have a few years of experience in the Linux ecosystem, and you’re interested in sharing that experience with the community, have a look at our Contribution Guidelines.

Comments are closed on this article!