Perl unpack Function
last modified April 4, 2025
The Perl unpack
function converts binary data into Perl values.
It's the inverse of pack
and essential for binary data processing.
unpack
uses template strings to specify how to interpret binary data.
It can extract numbers, strings, and other data types from binary structures.
Basic Definitions
- Template: String specifying data format (e.g., "N" for 32-bit unsigned integer)
- Binary data: Raw bytes that need interpretation
- Byte order: Endianness (big-endian vs little-endian)
- Alignment: Data structure padding requirements
- Fields: Individual data elements in the binary structure
Basic unpack Usage
The simplest use of unpack
extracts a single value from binary data.
#!/usr/bin/perl use strict; use warnings; use v5.34.0; my $binary = pack("N", 0xDEADBEEF); my ($number) = unpack("N", $binary); printf "Binary: %v02X\n", $binary; printf "Unpacked: 0x%08X\n", $number;
We pack a 32-bit unsigned integer and then unpack it. The "N" template specifies network (big-endian) byte order. The result matches our original value.
$ ./basic.pl Binary: DE.AD.BE.EF Unpacked: 0xDEADBEEF
Extracting Multiple Values
unpack
can extract multiple values with a single template.
#!/usr/bin/perl use strict; use warnings; use v5.34.0; my $data = pack("NnA4", 0xCAFEBABE, 42, "Perl"); my ($num1, $num2, $str) = unpack("NnA4", $data); printf "Numbers: 0x%08X, %d\n", $num1, $num2; print "String: $str\n";
This example packs and unpacks three values: a 32-bit integer, 16-bit integer, and 4-byte string. The template "NnA4" matches the packed data structure.
$ ./multiple.pl Numbers: 0xCAFEBABE, 42 String: Perl
Byte Order Conversion
unpack
can convert between different byte orders.
#!/usr/bin/perl use strict; use warnings; use v5.34.0; my $little_endian = pack("V", 0x12345678); my ($big_endian) = unpack("N", $little_endian); printf "Little-endian: %v02X\n", $little_endian; printf "Converted to big-endian: 0x%08X\n", $big_endian;
We pack a value in little-endian format ("V") and unpack it as big-endian ("N"). This demonstrates byte order conversion between different architectures.
$ ./endian.pl Little-endian: 78.56.34.12 Converted to big-endian: 0x78563412
String Extraction
unpack
can extract strings with specific lengths and encodings.
#!/usr/bin/perl use strict; use warnings; use v5.34.0; my $binary = pack("A10A5", "Hello", "World"); my ($str1, $str2) = unpack("A10A5", $binary); print "First string: '$str1'\n"; print "Second string: '$str2'\n";
This example packs and unpacks two space-padded strings. The "A" template extracts ASCII strings, trimming trailing spaces by default.
$ ./strings.pl First string: 'Hello' Second string: 'World'
Bit Manipulation
unpack
can extract individual bits and bitfields from binary data.
#!/usr/bin/perl use strict; use warnings; use v5.34.0; my $flags = pack("C", 0b10101100); my ($bitfield) = unpack("b8", $flags); print "Binary representation: $bitfield\n"; print "Bits 7-6: ", substr($bitfield, 0, 2), "\n"; print "Bit 3: ", substr($bitfield, 5, 1), "\n";
We pack a byte with specific bit patterns and unpack it as a binary string. The "b" template gives us access to individual bits for examination.
$ ./bits.pl Binary representation: 00110101 Bits 7-6: 00 Bit 3: 1
Hex Dump Parsing
unpack
can parse hexadecimal string representations of binary data.
#!/usr/bin/perl use strict; use warnings; use v5.34.0; my $hex_string = "DEADBEEFCAFE"; my $binary = pack("H*", $hex_string); my @bytes = unpack("C*", $binary); print "Hex string: $hex_string\n"; print "Bytes: ", join(", ", map { sprintf "0x%02X", $_ } @bytes), "\n";
This converts a hex string to binary and then unpacks it as individual bytes. The "H" template handles hex data, while "C" extracts unsigned bytes.
$ ./hexdump.pl Hex string: DEADBEEFCAFE Bytes: 0xDE, 0xAD, 0xBE, 0xEF, 0xCA, 0xFE
Complex Structure Parsing
unpack
can handle complex binary structures with mixed data types.
#!/usr/bin/perl use strict; use warnings; use v5.34.0; # Simulate a network packet header my $packet = pack("nnNNa8", 0x8000, # version and flags 42, # packet ID time(), # timestamp 128, # data length "payload" # data type ); my ($version_flags, $id, $timestamp, $length, $type) = unpack("nnNNa8", $packet); printf "Version: %d\n", ($version_flags >> 12) & 0xF; printf "Packet ID: %d\n", $id; printf "Timestamp: %s\n", scalar localtime $timestamp; printf "Data length: %d\n", $length; printf "Data type: '%s'\n", $type;
This example demonstrates parsing a complex binary structure resembling a network packet header. We extract and interpret multiple fields with different data types and sizes.
$ ./complex.pl Version: 8 Packet ID: 42 Timestamp: Wed Apr 5 14:30:22 2025 Data length: 128 Data type: 'payload'
Best Practices
- Validate input: Check binary data length before unpacking
- Use descriptive templates: Make formats readable and maintainable
- Handle endianness: Be explicit about byte order requirements
- Check return values: Verify unpacked data matches expectations
- Document formats: Comment complex binary structures thoroughly
Source
This tutorial covered Perl's unpack
function with practical
examples demonstrating binary data processing in various scenarios.
Author
List all Perl tutorials.