pack

(PHP 4, PHP 5, PHP 7)

packУпаковывает данные в бинарную строку

Описание

string pack ( string $format [, mixed $args [, mixed $... ]] )

Упаковывает заданные аргументы в бинарную строку согласно формату в параметре format.

Идея этой функции была заимствована из Perl и все коды форматирования работают также. Однако, есть некоторые отсутствующие коды форматирования, как, к примеру, код формата Perl "u".

Необходимо иметь ввиду, что отличие между знаковыми и беззнаковыми значениями влияет только на unpack() функцию, тогда как функция pack() дает одинаковый результат для знаковых и беззнаковых кодов формата.

Список параметров

format

Параметр format задается в виде строки и состоит из кодов формата и опционального аргумента повторения. Аргумент может быть целочисленным, либо * для повторения до конца введенных данных. Для a, A, h, H число повторений определяет то, сколько символов взято от одного аргумента данных, для @ - это абсолютная позиция для размещения следующих данных, для всего остального число повторений определяет как много аргументов данных было обработано и упаковано в результирующую бинарную строку.

Работающие на данный момент форматы:

Символы форматов функции pack()
Код Описание
a Строка (string) с NUL-заполнением
A Строка (string) со SPACE-заполнением
h Hex-строка (Hex string), с нижнего разряда
H Hex-строка (Hex string), с верхнего разряда
c знаковый символ (char)
C беззнаковый символ (char)
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)
q signed long long (всегда 64 bit, машинный порядок)
Q беззнаковый long long (всегда 64 bit, машинный порядок)
J беззнаковый long long (всегда 64 bit, порядок big endian)
P беззнаковый long long (всегда 64 bit, порядок little endian)
f float (машинно-зависимые размер и представление)
d double (машинно-зависимые размер и прдставление)
x NUL байт
X Резервирование одного байта
Z Строка (string) с NUL-заполнением (добавлено в PHP 5.5)
@ NUL-заполнение до абсолютной позиции

args

Возвращаемые значения

Возвращает бинарную строку, содержащую данные.

Список изменений

Версия Описание
5.6.3 Добавлены коды "q", "Q", "J" и "P" для поддержки 64-bit чисел.
5.5.0 Добавлен код "Z", работающий аналогично "a" для совместимости с Perl.

Примеры

Пример #1 Пример использования pack()

<?php
$binarydata 
pack("nvc*"0x12340x56786566);
?>

Полученная бинарная строка длиной 6 байт будет содержать последовательность байтов 0x12, 0x34, 0x78, 0x56, 0x41, 0x42.

Примечания

Предостережение

Необходимо отметить, что PHP сохраняет значения типа integer как знаковые с машинно-зависимым размером (C тип long). Все числа, переданные как integer, но выходящие за границы этого типа будут сохранены с типом float. При упаковке этих float как integer, они будут переданы с типом integer. Это может как совпадать, так и нет с заданным шаблоном.

Наиболее частым является случай, когда упаковываются беззнаковые числа типа integer. В системах, где integer имеет размер в 32 бита, число обычно передается по тому же шаблону, как если бы integer был беззнаковым (хотя, это зависит от определенных преобразований из знаковое в беззнаковое, согласно стандарту С). В системах, где тип integer имеет размер в 64 бита, тип float не имеет мантиссы, достаточной по размеру для хранения значения без потери точности. Если эти системы также имеют простой 64-битный С тип int (большинство UNIX систем не имеют), то единственным путем для использования формата I в верхнем разряде является создание отрицательных integer значений с тем же представлением как и в определенном беззнаковом значении.

Смотрите также

  • unpack() - Распаковывает данные из бинарной строки

Коментарии

Note that the the upper command in perl looks like this:

$binarydata = pack ("n v c*", 0x1234, 0x5678, 65, 66);
In PHP it seems that no whitespaces are allowed in the first parameter. So if you want to convert your pack command from perl -> PHP, don't forget to remove the whitespaces!
2000-08-10 07:14:26
http://php5.kiev.ua/manual/ru/function.pack.html
Автор:
You will get the same effect with

<?php
function _readInt($fp)
{
   return 
unpack('V'fread($fp4));
}
?>

or unpack('N', ...) for big-endianness.
2005-10-11 13:42:30
http://php5.kiev.ua/manual/ru/function.pack.html
Автор:
/* Convert float from HostOrder to Network Order */
function FToN( $val )
{
    $a = unpack("I",pack( "f",$val ));
    return pack("N",$a[1] );
}
   
/* Convert float from Network Order to HostOrder */
function NToF($val )
{
    $a = unpack("N",$val);
    $b = unpack("f",pack( "I",$a[1]));
    return $b[1];
}
2006-03-13 10:57:08
http://php5.kiev.ua/manual/ru/function.pack.html
Be aware of format code H always padding the 0 for byte-alignment to the right (for odd count of nibbles).

So pack("H", "7") results in 0x70 (ASCII character 'p') and not in 0x07 (BELL character)
as well as pack("H*", "347") results in 0x34 ('4') and 0x70 ('p') and not 0x03 and 0x47.
2008-05-08 10:26:17
http://php5.kiev.ua/manual/ru/function.pack.html
Автор:
Using pack to write Arabic char(s) to a file.

<?php
$text 
"&#13574;&#13830;&#13830;";

$text mb_convert_encoding($text"UCS-2BE""HTML-ENTITIES");

$len mb_strlen($text);

$bom mb_convert_encoding("&#65534;""unicode""HTML-ENTITIES");

$fp fopen('text.txt''w');

fwrite($fppack('a2'$bom)); 
fwrite($fppack("a{$len}"$text));
fwrite($fppack('a2'$bom)); 
fwrite($fppack('a2'"\n"));

fclose($fp);
?>
2010-06-21 07:53:15
http://php5.kiev.ua/manual/ru/function.pack.html
Автор:
If you need to unpack a signed short from big-endian or little-endian specifically, instead of machine-byte-order, you need only unpack it as the unsigned form, and then if the result is >= 2^15, subtract 2^16 from it.

And example would be:

<?php
$foo 
unpack("n"$signedbigendianshort);
$foo $foo[1];
if(
$foo >= pow(215)) $foo -= pow(216);
?>
2010-10-21 00:40:15
http://php5.kiev.ua/manual/ru/function.pack.html
If you'd like to understand pack/unpack. There is a tutorial here in perl, that works equally well in understanding it for php:

http://perldoc.perl.org/perlpacktut.html
2012-02-23 23:13:28
http://php5.kiev.ua/manual/ru/function.pack.html
Even though in a 64-bit architecure intval(6123456789) = 6123456789, and sprintf('%b', 5000000000) = 100101010000001011111001000000000
pack will not treat anything passed to it as 64-bit.  If you want to pack a 64-bit integer:

<?php
$big 
5000000000;

$left 0xffffffff00000000;
$right 0x00000000ffffffff;

$l = ($big $left) >>32;
$r $big $right;

$good pack('NN'$l$r);

$urlsafe str_replace(array('+','/'), array('-','_'), base64_encode($good));

//done!

//rebuild:
$unurl str_replace(array('-','_'), array('+','/'), $urlsafe);
$binary base64_decode($unurl);

$set unpack('N2'$tmp);
print_r($set);

$original $set[1] << 32 $set[2];
echo 
$original"\\r\\n";
?>

results in:
Array
(
    [1] => 1
    [2] => 705032704
)
5000000000

but ONLY on a 64-bit enabled machine and PHP distro.
2012-07-06 20:26:58
http://php5.kiev.ua/manual/ru/function.pack.html
A helper class to convert integer to binary strings and vice versa. Useful for writing and reading integers to / from files or sockets.

<?php

   
class int_helper
   
{
        public static function 
int8($i) {
            return 
is_int($i) ? pack("c"$i) : unpack("c"$i)[1];
        }

        public static function 
uInt8($i) {
            return 
is_int($i) ? pack("C"$i) : unpack("C"$i)[1];
        }

        public static function 
int16($i) {
            return 
is_int($i) ? pack("s"$i) : unpack("s"$i)[1];
        }

        public static function 
uInt16($i$endianness=false) {
           
$f is_int($i) ? "pack" "unpack";

            if (
$endianness === true) {  // big-endian
               
$i $f("n"$i);
            }
            else if (
$endianness === false) {  // little-endian
               
$i $f("v"$i);
            }
            else if (
$endianness === null) {  // machine byte order
               
$i $f("S"$i);
            }

            return 
is_array($i) ? $i[1] : $i;
        }

        public static function 
int32($i) {
            return 
is_int($i) ? pack("l"$i) : unpack("l"$i)[1];
        }

        public static function 
uInt32($i$endianness=false) {
           
$f is_int($i) ? "pack" "unpack";

            if (
$endianness === true) {  // big-endian
               
$i $f("N"$i);
            }
            else if (
$endianness === false) {  // little-endian
               
$i $f("V"$i);
            }
            else if (
$endianness === null) {  // machine byte order
               
$i $f("L"$i);
            }

            return 
is_array($i) ? $i[1] : $i;
        }

        public static function 
int64($i) {
            return 
is_int($i) ? pack("q"$i) : unpack("q"$i)[1];
        }

        public static function 
uInt64($i$endianness=false) {
           
$f is_int($i) ? "pack" "unpack";

            if (
$endianness === true) {  // big-endian
               
$i $f("J"$i);
            }
            else if (
$endianness === false) {  // little-endian
               
$i $f("P"$i);
            }
            else if (
$endianness === null) {  // machine byte order
               
$i $f("Q"$i);
            }

            return 
is_array($i) ? $i[1] : $i;
        }
    }
?>

Usage example:
<?php
    Header
("Content-Type: text/plain");
    include(
"int_helper.php");

    echo 
int_helper::uInt8(0x6b) . PHP_EOL// k
   
echo int_helper::uInt8(107) . PHP_EOL// k
   
echo int_helper::uInt8("\x6b") . PHP_EOL PHP_EOL// 107

   
echo int_helper::uInt16(4101) . PHP_EOL// \x05\x10
   
echo int_helper::uInt16("\x05\x10") . PHP_EOL// 4101
   
echo int_helper::uInt16("\x05\x10"true) . PHP_EOL PHP_EOL// 1296

   
echo int_helper::uInt32(2147483647) . PHP_EOL// \xff\xff\xff\x7f
   
echo int_helper::uInt32("\xff\xff\xff\x7f") . PHP_EOL PHP_EOL// 2147483647

    // Note: Test this with 64-bit build of PHP
   
echo int_helper::uInt64(9223372036854775807) . PHP_EOL// \xff\xff\xff\xff\xff\xff\xff\x7f
   
echo int_helper::uInt64("\xff\xff\xff\xff\xff\xff\xff\x7f") . PHP_EOL PHP_EOL// 9223372036854775807

?>
2016-05-29 06:14:51
http://php5.kiev.ua/manual/ru/function.pack.html
Автор:
pack()
h    Hex string, low nibble first (not same hex2bin())
H    Hex string, high nibble first (same hex2bin())
2017-07-11 08:45:02
http://php5.kiev.ua/manual/ru/function.pack.html

    Поддержать сайт на родительском проекте КГБ