﻿<h1 class=p1>Функции работы с бинарными данными</h1>
<table border="0" cellspacing="10">
    <tr valign="top">
        <td>
            <a class=bluelink href="#1" title="Функция упаковывки аргументов в бинарную строку">pack()</a>&nbsp;<br>
        </td>
        <td>
            <a class=bluelink href="#2" title="Функция распаковки данных из двоичной строки согласно формату">unpack()</a>&nbsp;<br>        
        </td>
    </tr>
</table>
<br>
<p class=text>Собственно, таких функций две – <b>pack()</b> и <b>unpack()</b>. Первая осуществляет пакетирование данных в двоичную строку, а вторая – распаковывает данные из двоичной строки. Лично у меня пока не было необходимости пользоваться этими функциями, кроме как при подготовке примеров их использования для этой главы. Но кто знает, может быть кому-то они очень нужны, поэтому мы с ними чуть-чуть повозимся.</p>
<p class=text>Итак, функция:</p>

<a name=1></a>
<h1 class=p1>pack()</h1>
<p class=prim><b><i>Синтаксис:</i></b></p>
<blockquote><pre>
string <b>pack</b><em class=gr>(</em>string <b>format</b> [ ,mixed <b>$args</b>, ...]<em class=gr>)</em>
</pre></blockquote>
<p class=text>Функция <b>pack()</b> упаковывает заданные в ее параметре аргументы в бинарную строку. Формат параметров и их количество задается при параметром <b>$format</b>, при помощи тех же спецификаторов форматирования, о которых мы говорили, только без знака <b>%</b>. После каждого спецификатора может стоять число, которое говорит о том, сколько информации будет обработано данным спецификатором. Для форматов <b>a</b>, <b>A</b>, <b>h</b> и <b>H</b> это число задает количество символов, которые будут помещены в бинарную строку из тех, что находятся параметре-строке при вызове функции (то есть, фактически определяется размер поля вывода строки). Если мы используем спецификатор &quot;<b>@</b>&quot;, то мы определяем абсолютную позицию, в которую будут помещены данные. Для всех остальных спецификаторов следующие за ними числа задают количество аргументов, на которые распространяется действие данного формата. Вместо числа можно указать <b>*</b>, в этом случае спецификатор действует на все оставшиеся данные. Заметим, что функция возвращает упакованные данные в шестнадцатеричном формате.</p>
<p class=text>Список спецификаторов формата:</p>
<ul>
  <li>a - строка, свободные места в поле заполняются символом с кодом 0; </li>
  <li>A - строка, свободные места заполняются пробелами; </li>
  <li>h - шестнадцатеричная строка, младшие разряды в начале; </li>
  <li>H - шестнадцатеричная строка, старшие разряды в начале; </li>
  <li>c - знаковый байт (символ); </li>
  <li>C - беззнаковый байт; </li>
  <li>s - знаковое короткое целое; </li>
  <li>S - беззнаковое короткое число; </li>
  <li>n - беззнаковое целое (16 битов, старшие разряды в конце); </li>
  <li>v - беззнаковое целое (16 битов, младшие разряды в конце); </li>
  <li>i - знаковое целое (размер и порядок байтов определяется архитектурой); </li>
  <li>I - беззнаковое целое; </li>
  <li>l - знаковое длинное целое (32 бита, порядок знаков определяется архитектурой); </li>
  <li>L - беззнаковое длинное целое; </li>
  <li>N - беззнаковое длинное целое (32 бита, старшие разряды в конце); </li>
  <li>V - беззнаковое целое (32 бита, младшие разряды в конце); </li>
  <li>f - число с плавающей точкой; </li>
  <li>d - число двойной точности; </li>
  <li>x - символ с нулевым кодом; </li>
  <li>X - возврат назад на 1 байт; </li>
  <li>@ - заполнение нулевым кодом до заданной абсолютной позиции.  </li>
</ul>
<br><br>
<a name=2></a>
<p class=text>Функция</p>
<h1 class=p1>unpack()</h1>
<p class=text>Как уже говорилось выше, Распаковывает данные из двоичной строки согласно формату. Функция возвращает массив, содержащий распакованные элементы.</p>
<p class=prim><b><i>Синтаксис:</i></b></p>
<blockquote><pre>
array <b>unpack</b><em class=gr>(</em>string <b>$format</b>, string <b>$data</b><em class=gr>)</em>
</pre></blockquote>
<p class=text>Давайте попробуем что-нибудь запаковать. К примеру, так.</p>
<blockquote><pre>
<em class=red>&lt;?</em>
   <b>$bin</b> = <b>pack</b><em class=gr>(</em>"nvn*",0x5722,0x1148, 65, 66<em class=gr>);</em> //<em class=comnt> запаковываем, согласно формату</em>
   <b>$var</b> = <b>bin2hex</b><em class=gr>(</em><b>$bin</b><em class=gr>);</em> // <em class=comnt>перекодируем из шестнадцатеричного формата</em>
   <em class=gr>echo(</em><b>$var</b><em class=gr>);</em>
<em class=red>?&gt;</em>
</pre></blockquote>
<p class=text>Итак, что мы увидели: функция вернула 6 байтов, причем в такой последовательности:</p>
<p class=text>0х57, 0х22, 0х48, 0х11, 0х00, 0х41, 0х00, 0х42. Понятно, почему так. Согласно заданному нами формату (nvn*), первое число мы возвращаем как беззнаковое целое со старшими разрядами в конце, второе тоже как беззнаковое целое, только в конце – младшие разряды (поэтому нам вернулось 0х48, 0х11, а не 0х11, 0х48), и все остальное до конца мы возвращаем как беззнаковое целое со старшими разрядами в конце.</p>
<br><br>