perlpacktut.html

来自「perl教程」· HTML 代码 · 共 756 行 · 第 1/5 页

HTML
756
字号
<?xml version="1.0" ?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<!-- saved from url=(0017)http://localhost/ -->
<script language="JavaScript" src="../../displayToc.js"></script>
<script language="JavaScript" src="../../tocParas.js"></script>
<script language="JavaScript" src="../../tocTab.js"></script>
<link rel="stylesheet" type="text/css" href="../../scineplex.css">
<title>perlpacktut - tutorial on C&lt;pack&gt; and C&lt;unpack&gt;</title>
<link rel="stylesheet" href="../../Active.css" type="text/css" />
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rev="made" href="mailto:" />
</head>

<body>

<script>writelinks('__top__',2);</script>
<h1><a>perlpacktut - tutorial on C&lt;pack&gt; and C&lt;unpack&gt;</a></h1>
<p><a name="__index__"></a></p>

<!-- INDEX BEGIN -->

<ul>

	<li><a href="#name">NAME</a></li>
	<li><a href="#description">DESCRIPTION</a></li>
	<li><a href="#the_basic_principle">The Basic Principle</a></li>
	<li><a href="#packing_text">Packing Text</a></li>
	<li><a href="#packing_numbers">Packing Numbers</a></li>
	<ul>

		<li><a href="#integers">Integers</a></li>
		<li><a href="#unpacking_a_stack_frame">Unpacking a Stack Frame</a></li>
		<li><a href="#how_to_eat_an_egg_on_a_net">How to Eat an Egg on a Net</a></li>
		<li><a href="#floating_point_numbers">Floating point Numbers</a></li>
	</ul>

	<li><a href="#exotic_templates">Exotic Templates</a></li>
	<ul>

		<li><a href="#bit_strings">Bit Strings</a></li>
		<li><a href="#uuencoding">Uuencoding</a></li>
		<li><a href="#doing_sums">Doing Sums</a></li>
		<li><a href="#unicode">Unicode</a></li>
		<li><a href="#another_portable_binary_encoding">Another Portable Binary Encoding</a></li>
	</ul>

	<li><a href="#template_grouping">Template Grouping</a></li>
	<li><a href="#lengths_and_widths">Lengths and Widths</a></li>
	<ul>

		<li><a href="#string_lengths">String Lengths</a></li>
		<li><a href="#dynamic_templates">Dynamic Templates</a></li>
		<li><a href="#counting_repetitions">Counting Repetitions</a></li>
	</ul>

	<li><a href="#packing_and_unpacking_c_structures">Packing and Unpacking C Structures</a></li>
	<ul>

		<li><a href="#the_alignment_pit">The Alignment Pit</a></li>
		<li><a href="#alignment__take_2">Alignment, Take 2</a></li>
		<li><a href="#alignment__take_3">Alignment, Take 3</a></li>
		<li><a href="#pointers_for_how_to_use_them">Pointers for How to Use Them</a></li>
	</ul>

	<li><a href="#pack_recipes">Pack Recipes</a></li>
	<li><a href="#funnies_section">Funnies Section</a></li>
	<li><a href="#authors">Authors</a></li>
</ul>
<!-- INDEX END -->

<hr />
<p>
</p>
<h1><a name="name">NAME</a></h1>
<p>perlpacktut - tutorial on <a href="../../lib/Pod/perlfunc.html#item_pack"><code>pack</code></a> and <a href="../../lib/Pod/perlfunc.html#item_unpack"><code>unpack</code></a></p>
<p>
</p>
<hr />
<h1><a name="description">DESCRIPTION</a></h1>
<p><a href="../../lib/Pod/perlfunc.html#item_pack"><code>pack</code></a> and <a href="../../lib/Pod/perlfunc.html#item_unpack"><code>unpack</code></a> are two functions for transforming data according
to a user-defined template, between the guarded way Perl stores values
and some well-defined representation as might be required in the 
environment of a Perl program. Unfortunately, they're also two of 
the most misunderstood and most often overlooked functions that Perl
provides. This tutorial will demystify them for you.</p>
<p>
</p>
<hr />
<h1><a name="the_basic_principle">The Basic Principle</a></h1>
<p>Most programming languages don't shelter the memory where variables are
stored. In C, for instance, you can take the address of some variable,
and the <code>sizeof</code> operator tells you how many bytes are allocated to
the variable. Using the address and the size, you may access the storage
to your heart's content.</p>
<p>In Perl, you just can't access memory at random, but the structural and
representational conversion provided by <a href="../../lib/Pod/perlfunc.html#item_pack"><code>pack</code></a> and <a href="../../lib/Pod/perlfunc.html#item_unpack"><code>unpack</code></a> is an
excellent alternative. The <a href="../../lib/Pod/perlfunc.html#item_pack"><code>pack</code></a> function converts values to a byte
sequence containing representations according to a given specification,
the so-called &quot;template&quot; argument. <a href="../../lib/Pod/perlfunc.html#item_unpack"><code>unpack</code></a> is the reverse process,
deriving some values from the contents of a string of bytes. (Be cautioned,
however, that not all that has been packed together can be neatly unpacked - 
a very common experience as seasoned travellers are likely to confirm.)</p>
<p>Why, you may ask, would you need a chunk of memory containing some values
in binary representation? One good reason is input and output accessing
some file, a device, or a network connection, whereby this binary
representation is either forced on you or will give you some benefit
in processing. Another cause is passing data to some system call that
is not available as a Perl function: <a href="../../lib/Pod/perlfunc.html#item_syscall"><code>syscall</code></a> requires you to provide
parameters stored in the way it happens in a C program. Even text processing 
(as shown in the next section) may be simplified with judicious usage 
of these two functions.</p>
<p>To see how (un)packing works, we'll start with a simple template
code where the conversion is in low gear: between the contents of a byte
sequence and a string of hexadecimal digits. Let's use <a href="../../lib/Pod/perlfunc.html#item_unpack"><code>unpack</code></a>, since
this is likely to remind you of a dump program, or some desperate last
message unfortunate programs are wont to throw at you before they expire
into the wild blue yonder. Assuming that the variable <code>$mem</code> holds a 
sequence of bytes that we'd like to inspect without assuming anything 
about its meaning, we can write</p>
<pre>
   <span class="keyword">my</span><span class="operator">(</span> <span class="variable">$hex</span> <span class="operator">)</span> <span class="operator">=</span> <span class="keyword">unpack</span><span class="operator">(</span> <span class="string">'H*'</span><span class="operator">,</span> <span class="variable">$mem</span> <span class="operator">);</span>
   <span class="keyword">print</span> <span class="string">"$hex\n"</span><span class="operator">;</span>
</pre>
<p>whereupon we might see something like this, with each pair of hex digits
corresponding to a byte:</p>
<pre>
   41204d414e204120504c414e20412043414e414c2050414e414d41</pre>
<p>What was in this chunk of memory? Numbers, characters, or a mixture of
both? Assuming that we're on a computer where ASCII (or some similar)
encoding is used: hexadecimal values in the range <code>0x40</code> - <code>0x5A</code>
indicate an uppercase letter, and <code>0x20</code> encodes a space. So we might
assume it is a piece of text, which some are able to read like a tabloid;
but others will have to get hold of an ASCII table and relive that
firstgrader feeling. Not caring too much about which way to read this,
we note that <a href="../../lib/Pod/perlfunc.html#item_unpack"><code>unpack</code></a> with the template code <code>H</code> converts the contents
of a sequence of bytes into the customary hexadecimal notation. Since
&quot;a sequence of&quot; is a pretty vague indication of quantity, <code>H</code> has been
defined to convert just a single hexadecimal digit unless it is followed
by a repeat count. An asterisk for the repeat count means to use whatever
remains.</p>
<p>The inverse operation - packing byte contents from a string of hexadecimal
digits - is just as easily written. For instance:</p>
<pre>
   <span class="keyword">my</span> <span class="variable">$s</span> <span class="operator">=</span> <span class="keyword">pack</span><span class="operator">(</span> <span class="string">'H2'</span> <span class="operator">x</span> <span class="number">10</span><span class="operator">,</span> <span class="keyword">map</span> <span class="operator">{</span> <span class="string">"3$_"</span> <span class="operator">}</span> <span class="operator">(</span> <span class="number">0</span><span class="operator">..</span><span class="number">9</span> <span class="operator">)</span> <span class="operator">);</span>
   <span class="keyword">print</span> <span class="string">"$s\n"</span><span class="operator">;</span>
</pre>
<p>Since we feed a list of ten 2-digit hexadecimal strings to <a href="../../lib/Pod/perlfunc.html#item_pack"><code>pack</code></a>, the
pack template should contain ten pack codes. If this is run on a computer
with ASCII character coding, it will print <code>0123456789</code>.</p>
<p>

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?