## Python’s binascii – hexlify() and unhexlify()

What the heck?

Today, a dear friend of mine came up to me and asked about the Python module binascii – particularly about the methods hexlify() and unhexlify(). Since he asked for it, I’m going to share my answer publicly with you.

First of all, I’m defining the used nomenclature:

- ASCII characters are being written in single quotes
- decimal numbers are of the type Long with a
*L*suffix - hex values have a
*x*prefix

First, let me quote the documentation:

`binascii.``b2a_hex`(*data*)`binascii.`

`hexlify`(

*data*)

*data*. Every byte of

*data*is converted into the corresponding 2-digit hex representation. The resulting string is therefore twice as long as the length of

*data*.

`binascii.`

`a2b_hex`(

*hexstr*)

`binascii.`

`unhexlify`(

*hexstr*)

*hexstr*. This function is the inverse of

`b2a_hex()`.

*hexstr*must contain an even number of hexadecimal digits (which can be upper or lower case), otherwise a

`TypeError`is raised.

I’ll begin with hexlify(). As the documentation states, this method splits a string which consists of hex-tuples into distinct bytes.

The ASCII character ‘A’ has 65L as numerical representation. To verify this in Python:

&gt;&gt;&gt; long(ord('A')) 65L

You might ask “Why is this even relevant to understand binascii?” Well, we don’t know anything about how ord() does its job. But with binascii we can re-calculate manually and verify.

&gt;&gt;&gt; binascii.hexlify('A') '41'

Now we know that an ‘A’ – interpreted as binary data and shown in hex – resembles ’41’. But wait, ’41’ is a string and no hex value! That’s no biggy, hexlify() represents its result as string.

To stay with the example, let’s convert 41 into a decimal number and check if it equals 65L.

&gt;&gt;&gt; long('41', 16) 65L

Tada! It seems that *‘A’ = 41 = 65L*.

You might have known that already, but please, stay with me a minute longer.

To make it look a little more complex:

&gt;&gt;&gt; binascii.hexlify('A') == &quot;%X&quot; % long('41', 16) True

Be aware that

&gt;&gt;&gt; &quot;%X&quot; %n

converts a decimal number into its hex representation.

——

binascii.unhexlify() naturally does the same thing as hexlify(), but in reverse. It takes binary data and displays it in tuples of hex-values.

I’ll start off with an example:

&gt;&gt;&gt; binascii.unhexlify('41') 'A' &gt;&gt;&gt; binascii.unhexlify(&quot;%X&quot; % ord('A')) 'A'

Here, unhexlify() takes the numerical representation 65L from the ASCII character ‘A’

&gt;&gt;&gt; ord('A') 65

converts it into hex 41

&gt;&gt;&gt; &quot;%X&quot; % ord('A') '41'

and represents it as a 1-tuple (meaning dimension of one) of hex values.

And now the conclusio – why might all of this be useful?

Right now, I can think of at least four use cases:

- cryptography
- data-transformation (i.e. Base64 for MIME/E-Mail attachements)
- security (deciphering binary readings off a network, pattern matching, …)
- textual representation of escape sequences

Taking up the last example, I’ll show you how to visualize the Bell esape sequence (you know, that thing that keeps *beep*ing in your terminal).

Taken from the ASCII table, the numerical representation of the Bell is 7. Programmers might know it better as a.

&gt;&gt;&gt; '7' == 'a' True

Presuming you read such a character in some kind of binary data – for example from a socket

&gt;&gt;&gt; foo = '7'

and you want to visualize this data

&gt;&gt;&gt; print foo

you will not get any results – at least none visible. You might hear the Bell sound if you’re not on a silent terminal.

Now, finally – binascii to the rescue:

&gt;&gt;&gt; binascii.hexlify('7') '07'

Voilà, the dubious string is decrypted.