Pack: примеры (PHP)
pack(string $format, mixed ...$values): stringФункция pack в PHP используется для упаковки данных в бинарную строку согласно указанному формату. Она преобразует данные из PHP-типов в бинарное представление, которое часто требуется при работе с файлами, сетевыми протоколами, шифрованием или взаимодействии с внешними системами.
Синтаксис функции: pack(string $format, mixed ...$values): string
Параметр $format - строка, определяющая формат упаковки. Состоит из кодов форматов:
- a - строка с NUL-дополнением
- A - строка с пробельным дополнением
- h - шестнадцатеричная строка, младший полубайт first
- H - шестнадцатеричная строка, старший полубайт first
- c - знаковый char (1 байт)
- C - беззнаковый char (1 байт)
- s - знаковый short (16 бит, порядок байт зависит от машины)
- S - беззнаковый short (16 бит)
- n - беззнаковый short (16 бит, big endian)
- v - беззнаковый short (16 бит, little endian)
- i - знаковый integer (зависит от размера и порядка байт)
- I - беззнаковый integer
- l - знаковый long (32 бита)
- L - беззнаковый long (32 бита)
- N - беззнаковый long (32 бита, big endian)
- V - беззнаковый long (32 бита, little endian)
- f - float (зависит от платформы)
- d - double (зависит от платформы)
- x - NUL-байт
- X - возврат на один байт
- @ - заполнение NUL-байтами до абсолютной позиции
Параметр ...$values - значения для упаковки. Их количество и типы должны соответствовать спецификаторам в формате.
echo bin2hex(pack('C', 65));41
echo bin2hex(pack('n', 258));0102
echo bin2hex(pack('A5', 'AB'));4142202020
echo bin2hex(pack('a5', 'AB'));4142000000
$data = pack('Cna5', 65, 258, 'test');
echo bin2hex($data);4101027465737400
unpack() - обратная функция для распаковки бинарных данных. Используется вместе с pack для полного цикла преобразований.
bin2hex() и hex2bin() - преобразуют бинарные данные в шестнадцатеричное представление и обратно. Проще для чтения человеком, но менее эффективны по объему.
sprintf() с %-форматами - подходит для форматирования строк, но не для бинарных данных. Не поддерживает порядок байт.
hash() с алгоритмами типа md5, sha256 - для хеширования, а не упаковки данных.
Функцию pack выбирают когда нужен точный контроль над бинарным представлением, особенно при работе с сетевыми протоколами или файловыми форматами.
import struct
result = struct.pack('>I', 123456)
print(result.hex())0001e240
const buffer = new ArrayBuffer(4);
const view = new DataView(buffer);
view.setUint32(0, 123456, false);
console.log(Array.from(new Uint8Array(buffer)).map(b => b.toString(16).padStart(2, '0')).join(''));0001e240
SELECT HEX('A'), UNHEX('41');41 | A
В отличие от PHP, в Python struct.pack требует явного указания порядка байт в формате. JavaScript работает с типизированными массивами, что более многословно. MySQL имеет ограниченные возможности для бинарной упаковки.
pack('CC', 65);Warning: pack(): 2 arguments expected, 1 provided
echo bin2hex(pack('C', 300));2c
Значение 300 обрезается до 44 (300 % 256).
pack('Z', 'test');Warning: pack(): Invalid format type Z
$little = pack('V', 123456);
$big = pack('N', 123456);
echo bin2hex($little), ' ', bin2hex($big);40e20100 0001e240
Разный результат на little-endian и big-endian системах если не указать явно порядок байт.
В PHP 7.2.0 добавлена поддержка форматов e, E, g и G для упаковки чисел с плавающей точкой с учетом порядка байт.
В PHP 8.0.0 улучшены сообщения об ошибках при несоответствии количества аргументов.
В PHP 8.1.0 добавлены форматы q, Q, j и J для 64-битных целых чисел с различными вариантами порядка байт.
echo bin2hex(pack('Q', 123456789012345));b9f4110700000000
$header = pack('CCnN', 0x45, 0x00, 1024, time());
echo bin2hex($header);450004000000000065b0f17d
$ip = pack('C4', 192, 168, 1, 1);
echo inet_ntop($ip);192.168.1.1
$float = pack('f', 3.14159);
echo bin2hex($float);d00f4940
$data = pack('a5@10a5', 'hello', 'world');
echo bin2hex($data);68656c6c6f000000000000000000776f726c6400
$struct = pack('NnA10f', 0x12345678, 0xABCD, 'test', 1.234);
echo bin2hex($struct);12345678abcd746573740000000000f46f9d3f
$hex = pack('H*', '48656c6c6f');
echo $hex;Hello
$uuid = pack('H*', sprintf('%04x%04x%04x%04x%04x%04x%04x%04x',
mt_rand(0, 0xffff), mt_rand(0, 0xffff),
mt_rand(0, 0xffff),
mt_rand(0, 0x0fff) | 0x4000,
mt_rand(0, 0x3fff) | 0x8000,
mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
));
echo bin2hex($uuid);f47ac10b58cc4372a5670a02b1e091ae