--- name: pack and unpack tutorial --- # pack and unpack — a tutorial [`pack`](../../p5/core/perlfunc/pack) and [`unpack`](../../p5/core/perlfunc/unpack) are Perl's low-level serialisers. They convert between Perl values and the raw byte strings that binary formats — network protocols, file headers, C structures, fixed-width records — actually carry on the wire. Most Perl programmers meet them rarely and forget them quickly. This tutorial is here so that when you do meet them, you already know the shape of the problem. ## When you need pack and unpack Reach for them when you are: - **Speaking a wire protocol** — DNS queries, TCP/IP headers, MQTT frames, anything with "big-endian 16-bit length" in its spec. - **Parsing a binary file format** — PNG, GIF, WAV, ELF, GZip, Intel HEX, all the formats whose first four bytes are a magic number followed by well-known integer fields. - **Slicing fixed-width text records** — log files, accounting ledgers, reports from mainframes. `unpack` is cleaner than chained `substr` calls and handles blank-field ambiguity that [`split`](../../p5/core/perlfunc/split) collapses. - **Passing data to a system call** — `syscall`, `ioctl`, and the rare `sockaddr_*` constructor expect bytes laid out as a C struct. For text serialisation (JSON, YAML, CSV, XML), reach for the appropriate module instead. `pack` is for binary. ## How this tutorial is organised Each chapter teaches one topic and stands on its own. You can read them in order, or jump to the one that answers your question. ```{toctree} :maxdepth: 1 bytes-and-widths endianness strings grouping-and-counts positioning network-protocols file-formats ``` - **Bytes and widths** — counting bytes, fixed-width integer directives, the native-vs-fixed distinction. - **Endianness** — byte order, the `<` / `>` modifiers, the portable `n` / `N` / `v` / `V` shortcuts. - **Strings** — `a` / `A` / `Z` (binary, text, C string), bit strings, hex strings. - **Grouping and counts** — `()` groups, repeat counts, `[…]` forms, the `/` item-count-prefix directive. - **Positioning** — `x` / `X` / `@` / `.` for moving around inside a template without producing a value. - **Network protocols** — build and parse a DNS query header. - **File formats** — parse a GIF header, the canonical "magic number plus fixed fields" file. Two chapters (*network-protocols*, *file-formats*) are full worked examples. Walk through one of them once you have read enough of the other chapters to recognise the directives. ## A first round-trip The shortest useful example of pack and unpack working together — packing a dotted-quad IP address into four raw bytes and reading it back: ```perl my $raw = pack "C4", 192, 168, 1, 42; # "\xc0\xa8\x01\x2a" my @octets = unpack "C4", $raw; # (192, 168, 1, 42) ``` `C` packs one unsigned byte; `C4` packs four of them in a row. On the way out, the same template pulls them back into a list of four integers. Every more complicated binary format is layered on top of that idea. ## Conventions in the examples - Expected output appears as an inline `# …` comment on the same line as the expression that produced it, or directly below the code block. - Examples run under a byte-oriented interpreter — no `use utf8`, no `use open` pragma changing layers. If a filehandle appears, assume `binmode $fh` has already been called. - Multi-byte constants such as `"\xc0\xa8\x01\x2a"` are written with hex escapes rather than raw byte values so the printed text matches what you see in the code.