pack - Perldoc Browser (original) (raw)

Takes a LIST of values and converts it into a string using the rules given by the TEMPLATE. The resulting string is the concatenation of the converted values. Typically, each converted value looks like its machine-level representation. For example, on 32-bit machines an integer may be represented by a sequence of 4 bytes, which will in Perl be presented as a string that's 4 characters long.

The TEMPLATE is a sequence of characters that give the order and type of values, as follows:

One or more modifiers below may optionally follow certain letters in the TEMPLATE (the second column lists letters for which the modifier is valid):

The > and < modifiers can also be used on () groups to force a particular byte-order on all components in that group, including all its subgroups.

This code:                             gives this result:  
unpack("W/a", "\004Gurusamy")          ("Guru")  
unpack("a3/A A*", "007 Bond  J ")      (" Bond", "J")  
unpack("a3 x2 /A A*", "007: Bond, J.") ("Bond, J", ".")  
pack("n/a* w/a","hello,","world")     "\000\006hello,\005world"  
pack("a/W2", ord("a") .. ord("z"))    "2ab"  

The length-item is not returned explicitly from unpack.
Supplying a count to the length-item format letter is only useful with A, a, or Z. Packing with a length-item of a or Z may introduce "\000" characters, which Perl does not regard as legal in numeric strings.

    printf "format s is %d, s! is %d\n",  
    length pack("s"), length pack("s!");  
    printf "format l is %d, l! is %d\n",  
    length pack("l"), length pack("l!");  

i! and I! are also allowed, but only for completeness' sake: they are identical to i and I.
The actual sizes (in bytes) of native shorts, ints, longs, and long longs on the platform where Perl was built are also available from the command line:

$ perl -V:{short,int,long{,long}}size  
shortsize='2';  
intsize='4';  
longsize='4';  
longlongsize='8';  

or programmatically via the Config module:

use Config;  
print $Config{shortsize},    "\n";  
print $Config{intsize},      "\n";  
print $Config{longsize},     "\n";  
print $Config{longlongsize}, "\n";  

$Config{longlongsize} is undefined on systems without long long support.

0x12 0x34 0x56 0x78  # big-endian  
0x78 0x56 0x34 0x12  # little-endian  

Basically, Intel and VAX CPUs are little-endian, while everybody else, including Motorola m68k/88k, PPC, Sparc, HP PA, Power, and Cray, are big-endian. Alpha and MIPS can be either: Digital/Compaq uses (well, used) them in little-endian mode, but SGI/Cray uses them in big-endian mode.
The names big-endian and little-endian are comic references to the egg-eating habits of the little-endian Lilliputians and the big-endian Blefuscudians from the classic Jonathan Swift satire, Gulliver's Travels. This entered computer lingo via the paper "On Holy Wars and a Plea for Peace" by Danny Cohen, USC/ISI IEN 137, April 1, 1980.
Some systems may have even weirder byte orders such as

0x56 0x78 0x12 0x34  
0x34 0x12 0x78 0x56  

These are called mid-endian, middle-endian, mixed-endian, or just weird.
You can determine your system endianness with this incantation:

printf("%#02x ", $_) for unpack("W*", pack L=>0x12345678);  

The byteorder on the platform where Perl was built is also available via Config:

use Config;  
print "$Config{byteorder}\n";  

or from the command line:

$ perl -V:byteorder  

Byteorders "1234" and "12345678" are little-endian; "4321" and "87654321" are big-endian. Systems with multiarchitecture binaries will have "ffff", signifying that static information doesn't work, one must use runtime probing.
For portably packed integers, either use the formats n, N, v, and V or else use the > and < modifiers described immediately below. See also perlport.

$ perl -CS -E 'say "\x{3B1}\x{3C9}"' |  
  perl -CS -ne 'printf "%v04X\n", <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mrow></mrow><mi>f</mi></msub><mi>o</mi><mi>r</mi><mi>u</mi><mi>n</mi><mi>p</mi><mi>a</mi><mi>c</mi><mi>k</mi><mo stretchy="false">(</mo><mi mathvariant="normal">&quot;</mi><mi>C</mi><mn>0</mn><mi>A</mi><mo>∗</mo><mi mathvariant="normal">&quot;</mi><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">_ for unpack(&quot;C0A*&quot;, </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.0361em;vertical-align:-0.2861em;"></span><span class="mord"><span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.10764em;">f</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2861em;"><span></span></span></span></span></span></span><span class="mord mathnormal" style="margin-right:0.02778em;">or</span><span class="mord mathnormal">u</span><span class="mord mathnormal">n</span><span class="mord mathnormal">p</span><span class="mord mathnormal">a</span><span class="mord mathnormal">c</span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mopen">(</span><span class="mord">&quot;</span><span class="mord mathnormal" style="margin-right:0.07153em;">C</span><span class="mord">0</span><span class="mord mathnormal">A</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="mord">&quot;</span><span class="mpunct">,</span></span></span></span>_)'  
03B1.03C9  
$ perl -CS -E 'say "\x{3B1}\x{3C9}"' |  
  perl -CS -ne 'printf "%v02X\n", <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mrow></mrow><mi>f</mi></msub><mi>o</mi><mi>r</mi><mi>u</mi><mi>n</mi><mi>p</mi><mi>a</mi><mi>c</mi><mi>k</mi><mo stretchy="false">(</mo><mi mathvariant="normal">&quot;</mi><mi>U</mi><mn>0</mn><mi>A</mi><mo>∗</mo><mi mathvariant="normal">&quot;</mi><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">_ for unpack(&quot;U0A*&quot;, </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.0361em;vertical-align:-0.2861em;"></span><span class="mord"><span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.10764em;">f</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2861em;"><span></span></span></span></span></span></span><span class="mord mathnormal" style="margin-right:0.02778em;">or</span><span class="mord mathnormal">u</span><span class="mord mathnormal">n</span><span class="mord mathnormal">p</span><span class="mord mathnormal">a</span><span class="mord mathnormal">c</span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mopen">(</span><span class="mord">&quot;</span><span class="mord mathnormal" style="margin-right:0.10903em;">U</span><span class="mord">0</span><span class="mord mathnormal">A</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="mord">&quot;</span><span class="mpunct">,</span></span></span></span>_)'  
CE.B1.CF.89  
$ perl -CS -E 'say "\x{3B1}\x{3C9}"' |  
  perl -C0 -ne 'printf "%v02X\n", <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mrow></mrow><mi>f</mi></msub><mi>o</mi><mi>r</mi><mi>u</mi><mi>n</mi><mi>p</mi><mi>a</mi><mi>c</mi><mi>k</mi><mo stretchy="false">(</mo><mi mathvariant="normal">&quot;</mi><mi>C</mi><mn>0</mn><mi>A</mi><mo>∗</mo><mi mathvariant="normal">&quot;</mi><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">_ for unpack(&quot;C0A*&quot;, </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.0361em;vertical-align:-0.2861em;"></span><span class="mord"><span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.10764em;">f</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2861em;"><span></span></span></span></span></span></span><span class="mord mathnormal" style="margin-right:0.02778em;">or</span><span class="mord mathnormal">u</span><span class="mord mathnormal">n</span><span class="mord mathnormal">p</span><span class="mord mathnormal">a</span><span class="mord mathnormal">c</span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mopen">(</span><span class="mord">&quot;</span><span class="mord mathnormal" style="margin-right:0.07153em;">C</span><span class="mord">0</span><span class="mord mathnormal">A</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="mord">&quot;</span><span class="mpunct">,</span></span></span></span>_)'  
CE.B1.CF.89  
$ perl -CS -E 'say "\x{3B1}\x{3C9}"' |  
  perl -C0 -ne 'printf "%v02X\n", <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mrow></mrow><mi>f</mi></msub><mi>o</mi><mi>r</mi><mi>u</mi><mi>n</mi><mi>p</mi><mi>a</mi><mi>c</mi><mi>k</mi><mo stretchy="false">(</mo><mi mathvariant="normal">&quot;</mi><mi>U</mi><mn>0</mn><mi>A</mi><mo>∗</mo><mi mathvariant="normal">&quot;</mi><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">_ for unpack(&quot;U0A*&quot;, </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.0361em;vertical-align:-0.2861em;"></span><span class="mord"><span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361em;"><span style="top:-2.55em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.10764em;">f</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2861em;"><span></span></span></span></span></span></span><span class="mord mathnormal" style="margin-right:0.02778em;">or</span><span class="mord mathnormal">u</span><span class="mord mathnormal">n</span><span class="mord mathnormal">p</span><span class="mord mathnormal">a</span><span class="mord mathnormal">c</span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mopen">(</span><span class="mord">&quot;</span><span class="mord mathnormal" style="margin-right:0.10903em;">U</span><span class="mord">0</span><span class="mord mathnormal">A</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="mord">&quot;</span><span class="mpunct">,</span></span></span></span>_)'  
C3.8E.C2.B1.C3.8F.C2.89  

Those examples also illustrate that you should not try to use pack/unpack as a substitute for the Encode module.

pack("@1A((@2A)@3A)", qw[X Y Z])  

is the string "\0X\0\0YZ".

    struct {  
    char   c;    /* one signed, 8-bit character */  
    double d;  
    char   cc[2];  
    }  

one may need to use the template c x![d] d c[2]. This assumes that doubles must be aligned to the size of double.
For alignment commands, a count of 0 is equivalent to a count of 1; both are no-ops.