ZetCode

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

Basic unpack Usage

The simplest use of unpack extracts a single value from binary data.

basic.pl
#!/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.

multiple.pl
#!/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.

endian.pl
#!/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.

strings.pl
#!/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.

bits.pl
#!/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.

hexdump.pl
#!/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.

complex.pl
#!/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

Source

Perl unpack Documentation

This tutorial covered Perl's unpack function with practical examples demonstrating binary data processing in various scenarios.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Perl tutorials.