Current Location: Home> Latest Articles> Using pack() and unpack() to implement bidirectional converters

Using pack() and unpack() to implement bidirectional converters

M66 2025-05-28

In PHP, pack() and unpack() are a pair of powerful functions that are often used to convert between binary data and human-readable formats. This article will take you through how to use these two functions to create a simple two-way data converter to realize the serialization and deserialization of data structures, and is suitable for file storage, network transmission and other scenarios.

Basic concepts

  • pack() : Pack one or more values ​​into binary strings according to the specified format.

  • unpack() : parses out the value from the binary string in the specified format.

The format codes of these two functions support multiple data types, such as integers, floating point types, strings, etc. Common format characters are:

Format characters meaning Occupying bytes
C Unsigned char 1 byte
n Unsigned short integer (big endian) 2 bytes
N Unsigned long (big endian) 4 bytes
a NUL fill string N bytes

Scenario setting: a simple data structure

Suppose we need to package and unpack the data of the following structure:

  • User ID (4 byte unsigned integer)

  • User level (1 byte)

  • Whether to activate (boolean values, represented by 0 and 1)

  • Username (fixed length string, 20 bytes)

What we want to achieve is:

  1. Use pack() to package these fields into a binary string.

  2. Use unpack() to re-parse the original data from this string.

Write a converter class

 class DataConverter {
    const FORMAT = 'Nid/Clevel/Cactive/a20username';

    public static function encode($data) {
        return pack(
            self::FORMAT,
            $data['id'],
            $data['level'],
            $data['active'] ? 1 : 0,
            $data['username']
        );
    }

    public static function decode($binary) {
        $result = unpack(self::FORMAT, $binary);
        $result['active'] = $result['active'] === 1;
        $result['username'] = rtrim($result['username'], "\0"); // Remove NUL filling
        return $result;
    }
}

Example of usage

 $data = [
    'id' => 123456,
    'level' => 5,
    'active' => true,
    'username' => 'm66user'
];

$binary = DataConverter::encode($data);
echo bin2hex($binary) . PHP_EOL;

$parsed = DataConverter::decode($binary);
print_r($parsed);

Output example (hexadecimal representation):

 0001e24005016d363675736572000000000000000000000000
Array
(
    [id] => 123456
    [level] => 5
    [active] => 1
    [username] => m66user
)

Application scenario expansion

Although this converter is simple, it can extend to more complex usage scenarios:

  • Network protocol packets, such as constructing and parsing socket communication data.

  • Serialization and deserialization of binary files.

  • Used when compact data storage (such as cache, embedded devices) is required.

For example, you can send the encoded data to a remote interface:

 file_put_contents("https://m66.net/api/upload", $binary);

Or load data from remote decoding: