Set Endianness in pack and unpack in PHP 8.6

Set Endianness in pack and unpack in PHP 8.6

Since PHP 8.6, the pack and unpack functions accept the < and > endianness modifiers, which set the byte order of the binary data. The < modifier means little-endian and > means big-endian. A modifier can be placed after one of these format codes:

  • s (signed 16-bit integer)
  • S (unsigned 16-bit integer)
  • l (signed 32-bit integer)
  • L (unsigned 32-bit integer)
  • q (signed 64-bit integer)
  • Q (unsigned 64-bit integer)
  • f (float, 32-bit)
  • d (double, 64-bit)

Before PHP 8.6, a fixed byte order was available only through separate format codes, such as N and V for unsigned integers, G and g for floats or E and e for doubles. Signed integers had no such codes and always used the byte order of the machine.

The following code packs the same integer in both byte orders and unpacks it back:

<?php

$value = 123456;
$little = pack('l<', $value);
$big = pack('l>', $value);

echo bin2hex($little).PHP_EOL; // 40e20100
echo bin2hex($big).PHP_EOL; // 0001e240

echo unpack('l<', $little)[1].PHP_EOL; // 123456
echo unpack('l>', $big)[1].PHP_EOL; // 123456

Both pack calls produce the same four bytes, but in reverse order. The unpack function returns an array. Its keys start from 1, because no name is specified after the format code.

The modifiers work the same way for floating-point numbers. For example, pack('f<', 1.5) returns the bytes 0000c03f, while pack('f>', 1.5) returns 3fc00000.

A ValueError is thrown if a modifier is used with a format code that does not support it.

Leave a Comment

Cancel reply

Your email address will not be published.