Broad Network


Converting Bytes to Hexadecimal Characters and Vice Versa with Perl

Perl pack and unpack Functions – Part 3

Writing a Perl Module

Foreword: In this part of the series, I explain how to convert bytes to hexadecimal characters and vice-versa, with Perl.

By: Chrysanthus Date Published: 27 Jan 2015

Introduction

This is part 3 of my series, Perl pack and unpack Functions. In this part of the series, I explain how to convert bytes to hexadecimal characters and vice-versa with Perl. You should have read the previous parts of the series before reaching here as this is a continuation.

Template
All what was discussed on template in the first part of the series is applicable here, but instead of A, you use H. Now, with the H meta character, consecutive bytes (characters) in the memory are not only separated (identified) or joined; but they are also converted to hexadecimal characters and vice-versa. For example, the byte, 01001110 would be converted to the characters, 4E and the characters; 4E would be converted to the byte, 01001110 . Note: with hexadecimal, the letter digits are case insensitive; so 4E is the same as 4e.

In the conversion from byte to hexadecimal characters, the bytes in memory are not changed. Yes, the bytes are converted into hexadecimal characters, but these resulting hexadecimal characters are stored elsewhere in memory. The hexadecimal characters are displayed from the new storage area, leaving the original bytes unchanged.

Now, a string of hexadecimal characters, displayed and stored somewhere in memory, can be converted into bytes and stored elsewhere in memory.

Remember, two consecutive hexadecimal characters would form a byte (8 bits), and conversion to-and-fro respects this.

Bytes to Hex

Converting Bytes to Hexadecimal Characters
I start with an example. Consider the following program:

use strict;

    my $str_B = "I love you.";
    my $str_H = unpack('H22', $str_B);

    print $str_H;

The output is:

    49206c6f766520796f752e

Now, in the variable, $str_B there are 11 characters including the space characters. Each of these characters is stored as a byte in memory. To convert consecutive bytes to displayable hexadecimal characters, use the unpack function. Each byte results in two hexadecimal characters, so for the 11 characters, the template has 22 after H (from 11 X 2).

Note that for the output, the two space characters have been displayed correctly, as 20. ‘I’ has been displayed in hexadecimal as 49 and not ‘I’. Lowercase ‘l’ has been displayed in hexadecimal as 6c, and not ‘l’. Do not confuse between the hexadecimal equivalent of a byte and the typed character, itself: The typed character is represented as a byte that has a hexadecimal equivalent. The converted hexadecimal characters are stored elsewhere in the memory and the original bytes of $str_B are not touched.

When you do not know the number of characters in the variable or in the memory region, use the * in the template, which means everything left, instead of a number like 22. The following statement illustrates this:

        my $str_H = unpack('H*', $str_B);

If the template is just 'H', only half a byte for one hexadecimal character will be unpacked. H means one hexadecimal character. H and H1 mean the same thing, but any other number means that number of hexadecimal characters.

The unpack function takes a variable as input and can return a list of values. The pack function can take a list as input and will return one value. So the template can be modified to something like,

    'H32H16H8'

to return three values: one for H32, one for H16 and one for H8.

Hex to Bytes

Conversion from Hexadecimal Characters to Bytes
Bytes are stored in memory. Hexadecimal characters are also stored in memory, but it is their display or typing that is important in this series. I use the reverse of the above code to explain the conversion here. Consider the following code:

use strict;

    my $str_H = "49206c6f766520796f752e";
    my $str_B = pack('H22', $str_H);

    print $str_B;

The output is:

    I love you.

Now, in the variable, $str_H there are 22 hexadecimal characters including the space character pairs. A hexadecimal string of characters should be considered as consecutive pairs of characters, where each pair will be stored as a byte in memory. To convert consecutive pairs of displayed (typed) hexadecimal characters to be stored as bytes, use the pack function. Each pair results in one byte stored. The 22 in the template refer to the number of hexadecimal characters to be converted and not the number of resulting bytes, which is 11.  In the code above, the 22 refer to the displayed (typed) hexadecimal characters.

Note that for the output, the two space hexadecimal character pairs of 20, have been interpreted correctly, as ‘ ’. 49 has been interpreted as ‘I’. 6c has been interpreted as ‘l’. 2e has been interpreted correctly as the full-stop character. Do not confuse between the hexadecimal equivalent of a byte and the typed character, itself: The typed character is represented as a byte that has a hexadecimal equivalent. The converted bytes of interest are stored in the memory, as the value of the variable, $str_B, while the hexadecimal characters are stored elsewhere (still in memory).

When you do not know the number of hexadecimal characters in the variable, use the * in the template, which means everything left, instead of a number like 22. The following statement illustrates this:

        my $str_B = pack('H*', $str_H);

If the template is just 'H', only one character will be packed. H means one hexadecimal character. H and H1 mean the same thing, but any other number means that number of hexadecimal characters.

The unpack function takes a variable as input and can return a list of values. The pack function can take a list as input and will return one value. So, for the above code, the template can be modified to something like,

    'H32H16H8'

to return one value of bytes, which is the direct conversion from consecutive hexadecimal character pairs. The bytes resulting from H32 will be joined to the byte resulting from H16, which will be joined to the byte resulting from H8, in that order from left to right.

String value for pack Function
Instead of coding,

    my $str_B = pack('H22', $str_H);

you can code,

    my $str_B = pack('H22', "49206c6f766520796f752e");

replacing $str_H with a string in quotes.

Remember, whether you are dealing with the pack or unpack function, the template is in single or double quotes.

Zero and Hex String
Note, when dealing with hexadecimal strings as in the above code samples, ‘O’ of the alphabet, can never be a character in the string. However, 0 of the numbers, meaning, zero, can be a character in the string.

And that is it for this part of the series. We stop here and continue in the next part.

Chrys

Related Links

Internet Sockets and Perl
Perl pack and unpack Functions
Writing MySQL Protocol Packets in PurePerl
Developing a PurePerl MySQL API
Using the PurePerl MySQL API
Database
Perl Course
MySQL Course
More Related Links
Perl Mailsend
PurePerl MySQL API
Perl Course - Professional and Advanced
Major in Website Design
Web Development Course
Producing a Pure Perl Library
MySQL Course

BACK NEXT

Comments

Become the Writer's Fan
Send the Writer a Message