Some Applications of the Perl pack and unpack Functions
Perl pack and unpack Functions – Part 6
Writing a Perl Module
Foreword: In this part of the series, I talk about some applications of the pack and unpack functions in Perl.
By: Chrysanthus Date Published: 27 Jan 2015
Introduction
Binary Bit Shifting
Perl has an operator called the binary Left Shift Bitwise operator, whose symbol is, <<. Perl also has an operator called the binary Right Shift Bitwise operator, whose symbol is, >>.
Binary << returns the value of its left argument shifted left by the number of bits specified by the right argument. Arguments (operands) should be decimal integers.
Binary >> returns the value of its left argument shifted right by the number of bits specified by the right argument. Arguments (operands) should be decimal integers.
The circular left shift operation S^n(X), which is different from the normal left bitwise operation, where X is a word and n is an integer with 0 <= n < 32, is defined by
S^n(X) = (X << n) OR (X >> 32-n)
In this logical function, X << n is obtained as follows: discard the left-most n bits of X and then pad the result with n zeroes on the right (the result will still be 32 bits). X >> n is obtained by discarding the right-most n bits of X and then padding the result with n zeroes on the left. Thus S^n(X) is equivalent to a circular shift of X by n positions to the left. Note that after the OR in the function, you have 32-n and not only n. With Perl << is the normal left bitwise operation and >> is the normal right bitwise operation.
In the logical function, OR is the bitwise OR. You can do bitwise OR between two bytes of the same length using the Perl bitwiase OR operator, | .
The following code does the circular shift operation for a word, where n is 5. The word is given in hexadecimal (string).
use strict;
#do S^5(P)
my $P = pack('H8', "6ED9EBA1");
my $PD = unpack('L>', $P );
my $PDL = $PD << 5;
my $PDR = $PD >> 27;
my $PDLB = pack('L>', $PDL);
my $PDRB = pack('L>', $PDR);
my $CircA = $PDLB | $PDRB;
print unpack('H8', $CircA);
The output in hexadecimal is,
db3d742d
The code first of all packs the hexadecimal string characters into a byte sequence. It then unpacks the result into a decimal number (integer). It then does the two shifting resulting in two decimal numbers (integers). Even though shifting is done on decimal numbers, it is actually bitwise shifting taking place underneath. Perl allows bitwise shifting only for decimal integers. The resulting two decimal numbers are then packed into bytes (4 bytes make 1 word; 8 hexadecimal digits make 1 word). The new byte sequence are bitwise ORed. The result is displayed as a hexadecimal number.
The operation X + Y can be defined as follows: words X and Y represent decimal integers x and y, where 0 <= x < 2^32 and 0 <= y < 2^32. Note: 2^32 means 2 raised to the power 32. For positive integers n and m, let n mod m be the remainder upon dividing n by m. Compute
z = (x + y) mod 2^32.
Then 0 <= z < 2^32. Convert z to a word, Z, and define Z = X + Y.
The following code illustrates this with the input numbers in hexadecimal (strings)
use strict;
#do C = B + A
my $XB = pack('H8', "10325476"); #for B
my $XA = pack('H8', "C3D2E1F0"); #for A
my $xb = unpack('L>', $XB);
my $xa = unpack('L>', $XA);
my $xba = ($xb + $xa) % 4294967296;
my $C = pack('L>', $xba);
print unpack('H8', $C);
The output is:
d4053666
The two hexadecimal strings are packed into byte sequences. The resulting byte sequences are converted into decimal numbers (integers). The special modulo addition is then dome with the decimal numbers. The resulting decimal number is packed back to a byte sequence. This byte sequence is displayed in hexadecimal.
Series Summary
When the template meta character is A, packing brings bytes together and unpacking separates bytes. When the template meta character is not A, as well as bringing bytes together, packing converts a hexadecimal string to bytes or a bit string to bytes or a decimal number to bytes. When the template meta character is not A, as well as separating bytes, unpacking converts a byte sequence to hexadecimal string or a byte sequence to bit string or a byte sequence to decimal number.
That is it for this part of the series.
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