Converting Bytes to Numbers and Vice versa with Perl
Perl pack and unpack Functions – Part 5
Writing a Perl Module
Foreword: In this part of the series, I explain how to convert bytes to decimal integers and vice-versa with Perl.
By: Chrysanthus Date Published: 27 Jan 2015
Introduction
Template
All what was discussed on template in the first part of the series is applicable here, but instead of A, you use S, L, Q, s, l, q, S>, L>, Q>, s>, l>, q>, S<, L<, Q<, s<, l<, or q< . Each of these meta characters either does conversion from bytes to number or number to bytes.
In the conversion from bytes to integers, the bytes in memory are not changed. Yes, the bytes are converted into integers, but these resulting integers are stored elsewhere in memory. The integers are displayed from the new storage area, leaving the original bytes unchanged.
Note: an integer displayed and stored somewhere in memory, can be converted into bytes and stored elsewhere in memory.
Peculiarities with Numbers
The hexadecimal number, 49 would be stored in memory as the byte, 01001001. If you have read the previous parts of the series, then you should know that this byte is the way the computer records the alphabet letter, ‘I’. This byte is printed (displayed) as ‘I’.
Note: when dealing with hexadecimal strings and the H template meta character, ‘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.
The hexadecimal string 03 is stored in memory as the byte, 00000011. This byte is actually the memory record for the love character, ♥. It is not the decimal number, 3; it is the hexadecimal number, 3. Do not confuse between a hexadecimal number or character and a decimal number.
In mathematics, integers are: - - - -3, -2, -1, 0, +1, +2, +3 - - - . In mathematics, integers are signed numbers. The set of integers can still be written as, - - - -3, -2, -1, 0, 1, 2, 3 - - -; here the plus signs have been omitted. In programming, positive numbers can be called, unsigned numbers. In programming, the words “sign” and “unsigned”, have the meanings given in this paragraph.
All decimal integers below 256 can each be stored as one byte. However, a computer stores an integer either in 2 bytes, 4 bytes or 8 bytes. 2 bytes consist of 16 bits; 4 bytes consist of 32 bits and 8 bytes consist of 64 bits.
Now, you do not have to understand the peculiarities in numbering and programming before you use Perl to convert bytes to decimal integers and vice-versa. All you have to remember is the rules given below:
In developing the pack and unpack functions, the following points were taking into consideration:
- the number of bytes used for storing the integer;
- whether the contents are interpreted as a signed or unsigned number;
- the byte ordering: whether the first byte is the least or most significant byte.
Template Meta Characters
- C is for packing and unpacking a decimal unsigned character integer into 8 bits.
- S is for packing and unpacking a decimal unsigned integer into 16 bits.
- L is for packing and unpacking a decimal unsigned integer into 32 bits.
- Q is for packing and unpacking a decimal unsigned integer into 64 bits.
- s is for packing and unpacking a decimal signed integer into 16 bits.
- l is for packing and unpacking a decimal signed integer into 32 bits.
- q is for packing and unpacking a decimal signed integer into 64 bits.
> is also a meta character but it has to be typed immediately after any of the above meta characters. > is for having the decimal integer bytes with the most significant byte first (on the left) as in normal base 2 (bit) counting, and the rest of the bytes follow in order of importance. Here we are dealing with byte ordering and not bit ordering. Within a byte the ordering is MSB first (normal) for the above meta characters.
< is also a meta character but it has to be typed immediately after any of the above letter meta characters. < is for having the decimal integer bytes with the most significant byte last (on the right), and the rest of the bytes precede in order of importance. Here again, we are dealing with byte ordering and not bit ordering. Within a byte the ordering is MSB first (normal) for the above meta characters.
Note: between > and <, < is the default. So, if you want the effect of <, you can still omit typing it.
You pack a decimal integer into bytes and you unpack a byte sequence into an integer in a similar way to packing and unpacking hexadecimal and binary sequence of bytes; just respect the use of the above meta characters in the template.
The print function prints or displays bytes as characters. So if a number has been packed into 16 bits, the print function will display two characters for the 16 bits, when asked to print the bytes; if the number has been packed into 32 bits, the print function will display 4 characters, one character for each byte; if the number has been packed into 64 bits, the print function will display 8 characters, one character for each byte; when asked to print the bytes. Note, a character (byte) displayed may be a space.
In the following code there are two segments. The first segment packs numbers into bytes. The byte sequence for each number is displayed in bit strings. The characters of the bytes for each number are displayed. The unpacked byte sequence (resulting in the original number) is displayed. Note that when you pack, you produce bytes, and when you unpack, you produce what the ordinary user would understand. The second code segment does the same things but uses the > meta character. If you use the > character for packing, you should use it for unpacking. Also, if you use the < character for packing, you should use it for unpacking.
use strict;
my $str_Byt16 = pack('S', 315);
print unpack('B16', $str_Byt16), "\n";
print $str_Byt16, "\n";
print unpack('S', $str_Byt16), "\n";
my $str_Byt32 = pack('L', 315);
print unpack('B32', $str_Byt32), "\n";
print $str_Byt32, "\n";
print unpack('L', $str_Byt32), "\n";
my $str_Byt64 = pack('Q', 315);
print unpack('B64', $str_Byt64), "\n";
print $str_Byt64, "\n";
print unpack('Q', $str_Byt64), "\n\n";
my $str_Byt16g = pack('S>', 315);
print unpack('B16', $str_Byt16g), "\n";
print $str_Byt16g, "\n";
print unpack('S>', $str_Byt16g), "\n";
my $str_Byt32g = pack('L>', 315);
print unpack('B32', $str_Byt32g), "\n";
print $str_Byt32g, "\n";
print unpack('L>', $str_Byt32g), "\n";
my $str_Byt64g = pack('Q>', 315);
print unpack('B64', $str_Byt64g), "\n";
print $str_Byt64g, "\n";
print unpack('Q>', $str_Byt64g), "\n";
The output is:
0011101100000001
;☺
315
00111011000000010000000000000000
;☺
315
0011101100000001000000000000000000000000000000000000000000000000
;☺
315
0000000100111011
☺;
315
00000000000000000000000100111011
☺;
315
0000000000000000000000000000000000000000000000000000000100111011
☺;
315
Note that between corresponding statements, there has been byte ordering and not bit ordering within a byte. The b meta character has not been used in the code to bring about bit ordering (LSB) within a byte.
You should retry the code changing any < to > to see the effects. Retry the code again, changing any S to s, any L to l, and any Q to q. Retry the code yet again, changing any < back to > with the previous s, l and q maintained.
The Packing and Unpacking Template
If you use s to pack, you have to use the same s to unpack. If you use S to pack, you have to use the same S to unpack. If you use l to pack, you have to use the same l to unpack. If you use q to pack, you have to use the same q to unpack. If you use Q to pack, you have to use the same Q to unpack. If you use < to pack, you have to use the same < to unpack. If you use > to pack, you have to use the same > to unpack.
That is it for this part of the series. We stop here and continue in the next part.
Chrys
Related Links
Internet Sockets and PerlPerl 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