LINUX.ORG.RU

php распаковать бинарную строку

 , двоичная,


0

1

Дана бинарная строка, в которой, например, 1056 байта. Строку получаю в big endian. Но программа будет работать на Intel т.е little endian?

В строке каждые 4 байта это значние float.

  $index = 0;
  $out = bin2hex($buffer);
  $result_array = array();
  $tmpbuffer = array(4); // массив для каждых 4-х байтов
  for ($i = 0; $i < 1024/4; $i++) {
      $index = $i*4;
      $tmpbuffer[0] = $out[$index];
      $tmpbuffer[1] = $out[$index+1];
      $tmpbuffer[2] = $out[$index+2];
      $tmpbuffer[3] = $out[$index+3];
      array_push($result_array, unpack("f", $tmpbuffer)); // 4 байта распаковываем в одно значение float и отправляем в результирующий массив
  }

Вопрос: как это правильно сделать?

★★★★★

Последнее исправление: sniper21 (всего исправлений: 1)

1. bin2hex не нужен.

2. $tmpbuffer должен быть строкой.

3. В новых версиях php можно сделать сразу unpack(«G*», $buffer).

amm ★★
()
Ответ на: комментарий от amm

1. bin2hex не нужен.

2. $tmpbuffer должен быть строкой.

  $index = 0;
  $result_array = array();
  $tmpbuffer = '';
  for ($i = 0; $i < 1056/4; $i++) {
      $index = $i*4;
      $tmpbuffer[0] = $buffer[$index];
      $tmpbuffer[1] = $buffer[$index+1];
      $tmpbuffer[2] = $buffer[$index+2];
      $tmpbuffer[3] = $buffer[$index+3];
      array_push($result_array, unpack("f", $tmpbuffer));
  }
array(528) { [0]=> NULL [1]=> NULL [2]=> NULL [3]=> NULL [4]=> NULL [5]=> NULL [6]=> NULL [7]=> NULL [8]=> NULL [9]=> NULL [10]=> NULL [11]=> NULL [12]=> NULL ...

3. В новых версиях php можно сделать сразу unpack(«G*», $buffer).

В моей версии PHP возвращает bool(false)

# php -v

PHP 5.4.16 (cli) (built: Apr 12 2018 19:02:01)

sniper21 ★★★★★
() автор топика
Ответ на: комментарий от sniper21

PHP 5.4.16 (cli) (built: Apr 12 2018 19:02:01)

За что вам такая древность?

  for ($i = 0; $i < 1056/4; $i++) {
      $tmpbuffer = '';
      $index=$i*4;
      $tmpbuffer .= $mybuf[$index+3];
      $tmpbuffer .= $mybuf[$index+2];
      $tmpbuffer .= $mybuf[$index+1];
      $tmpbuffer .= $mybuf[$index];
      array_push($result_array, unpack("f", $tmpbuffer));  
    }

madcore ★★★★★
()
Последнее исправление: madcore (всего исправлений: 1)
Ответ на: комментарий от madcore

За что вам такая древность?

За что что корпоративно, стабильно, надежно. Это CentOS 7.5.

За помощь спасибо, погодите-ка. Распаковал, но все значения, почему-то одинаковые....

sniper21 ★★★★★
() автор топика
Последнее исправление: sniper21 (всего исправлений: 1)
Ответ на: комментарий от sniper21

Но, это же ...

Это можно запомнить, и даже понять, почему так работает. Но вот можно ли такое простить?))

amm ★★
()
Ответ на: комментарий от sniper21

Вероятно, что-то не так с исходным буфером.
Что на php 5.4 такой код что выдаст?

$mybuf=hex2bin('3F99999A3FA6666640B9999A4048F5C34039999A');

$result_array=array();
for ($i = 0; $i < 5; $i++) {
    $tmpbuffer = '';
    $index=$i*4;
    $tmpbuffer .= $mybuf[$index+3];
    $tmpbuffer .= $mybuf[$index+2];
    $tmpbuffer .= $mybuf[$index+1];
    $tmpbuffer .= $mybuf[$index];
    $tmpbuffer = strrev(substr($mybuf,$index,4));
    array_push($result_array, unpack("f", $tmpbuffer));  
}
print_r($result_array);

$result_array=array();
for ($i = 0; $i < 5; $i++) {
    array_push($result_array, unpack("f", strrev(substr($mybuf, $i*4, 4))));  
}
print_r($result_array);

madcore ★★★★★
()
Ответ на: комментарий от sniper21

За что что корпоративно, стабильно, надежно. Это CentOS 7.5.

Redhat раздавал php 7.x через Software Collections (scl). Еще есть несколько сторонних репозиториев с php 7.x (remi, ius).

За помощь спасибо, погодите-ка. Распаковал, но все значения, почему-то одинаковые....

А должны быть разные?

amm ★★
()
Ответ на: комментарий от madcore
Array
(
    [0] => Array
        (
            [1] => 1.2000000476837
        )

    [1] => Array
        (
            [1] => 1.2999999523163
        )

    [2] => Array
        (
            [1] => 5.8000001907349
        )

    [3] => Array
        (
            [1] => 3.1400001049042
        )

    [4] => Array
        (
            [1] => 2.9000000953674
        )

)
Array
(
    [0] => Array
        (
            [1] => 1.2000000476837
        )

    [1] => Array
        (
            [1] => 1.2999999523163
        )

    [2] => Array
        (
            [1] => 5.8000001907349
        )

    [3] => Array
        (
            [1] => 3.1400001049042
        )

    [4] => Array
        (
            [1] => 2.9000000953674
        )

)
sniper21 ★★★★★
() автор топика
Ответ на: комментарий от sniper21

Значит правильно работает.

Ну и из приведенного фрагмента кода не совсем ясно,

array_push($result_array, unpack(«f», $tmpbuffer));

Учитывается ли дальше, что unpack возвращает массив?
Если пихать нужно число, то как-то так
array_push($result_array, unpack(«f», $tmpbuffer)[1]);

madcore ★★★★★
()
Ответ на: комментарий от theNamelessOne

использует версию, на которую уже не выходят security-патчи.

у нас для этого сильно закрытая сеть.

sniper21 ★★★★★
() автор топика
Ответ на: комментарий от sniper21

На Питоне распаковка делается так:

В php7 unpack так тоже умеет, а рабочие примеры для 5.4 я привел.

madcore ★★★★★
()

а в чем вопрос-то?

$tmpbuffer[0] = $out[$index];
$tmpbuffer[1] = $out[$index+1];
$tmpbuffer[2] = $out[$index+2];
$tmpbuffer[3] = $out[$index+3];

кстати в строковых функциях есть substr(), он тупой и работает с байтами.

thomasbug
()
Ответ на: комментарий от thomasbug

Так чтоли? Работает, но на выходе получается не то.

  $bytes_per_float = 4;
  $stack = array();
  $tmpbuffer = '';
  for ($i=0; $i<1056/$bytes_per_float; $i++) {
      $tmpbuffer = substr($buffer,i*4,i*4+4);     
      array_push($stack, unpack("f", $tmpbuffer));
  }
sniper21 ★★★★★
() автор топика
Ответ на: комментарий от sniper21

оч давно не трогал пхп, но предполагаю, что третий аргумент substr ты понял неправильно.

на выходе получается не то

вообще, знаешь ли, программы принято _отлаживать_, т.е. разбираться, что в той или иной точке должно быть и что есть фактически

thomasbug
()
Ответ на: комментарий от sniper21

Работает, но на выходе получается не то.

А что должно получиться-то? Все должно работать. Если не хватает двух примеров от madcore, держи третий:

var_dump(array_reverse(unpack("f*", strrev($buffer))));
amm ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.