Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

perl perlpacktut not making sense for me

Tags:

perl

I am REALLY confused about pack and unpack definition for perl. Below is the excerpt from perl.doc.org

The pack function converts values to a byte sequence containing representations according to a given specification, the so-called "template" argument. unpack is the reverse process, deriving some values from the contents of a string of bytes.

So I get the idea that pack takes human readable things(such as A) and turn it into binary format. Am I wrong on this interpretation??

So that is my interpreation but then same doc immediately proceeds to put this example which put my understanding exactly the opposite.

my( $hex ) = unpack( 'H*', $mem );
print "$hex\n";

What am I missing?

like image 437
user3502374 Avatar asked Mar 08 '23 15:03

user3502374


1 Answers

The pack function puts one or more things together in a single string. It represents things as octets (bytes) in a way that it can unpack reliably in some other program. That program might be far away (like, the distance to Mars far away). It doesn't matter if it starts as something human readable or not. That's not the point.

Consider some task where you have a numeric ID that's up to about 65,000 and a string that might be up to six characters.

print pack 'S A6', 137, $ARGV[0];

It's easier to see what this is doing if you run it through a hex dumper as you run it:

$ perl pack.pl Snoopy | hexdump -C
00000000  89 00 53 6e 6f 6f 70 79                           |..Snoopy|

The first column counts the position in the output so ignore that. Then the first two octets represent the S (short, 'word', whatever, but two octets) format. I gave it the number 137 and it stored that as 0x8900. Then it stored 'Snoopy' in the next six octets.

Now try it with a shorter name:

$ perl test.pl Linus | hexdump -C
00000000  89 00 4c 69 6e 75 73 20                           |..Linus |

Now there's a space character at the end (0x20). The packed data still has six octets. Try it with a longer name:

$ perl test.pl 'Peppermint Patty' | hexdump -C
00000000  89 00 50 65 70 70 65 72                           |..Pepper|

Now it truncates the string to fit the six available spaces.

Consider the case where you immediately send this through a socket or some other way of communicating with something else. The thing on the other side knows it's going to get eight octets. It also knows that the first two will be the short and the next six will be the name. Suppose the other side stored that it $tidy_little_package. It gets the separate values by unpacking them:

my( $id, $name ) = unpack 'S A6', $tidy_little_package;

That's the idea. You can represent many values of different types in a binary format that's completely reversible. You send that packed string wherever it needs to be used.

I have many more examples of pack in Learning Perl and Programming Perl.

like image 117
brian d foy Avatar answered Mar 14 '23 21:03

brian d foy