Бинарное чтение, парсер

pavlik35

Новичок
Добрый вечер. Пытаюсь прочитать бинарик.

PHP:
$binaryData = file_get_contents($filename);

$formatData =
    'A8Header';
   
$data = unpack($formatData, $binaryData);
При таком раскладе получаем так:
array(1) {
["Header"]=>
string(6) "MRTT"
}
Стоит поменять формат на 'd8Header', получаю следующее:
array(8) {
["Header1"]=>
float(5.97264354466E-154)
["Header2"]=>
float(6.01329361885E-154)
["Header3"]=>
float(5.99464662898E-154)
["Header4"]=>
float(6.01349277804E-154)
["Header5"]=>
float(6.013470017E-154)
["Header6"]=>
float(4.25997034901E-270)
["Header7"]=>
float(6.01347001588E-154)
["Header8"]=>
float(6.013470017E-154)
}
По итогу хочу прочитать первые 8 байт в виде double.
Почему он выводит мне 8 раз?
Спасибо.
 

Активист

Активист
Команда форума
Потому что формат кривой используете. У вас сколько байт число? Вообще в спецификации к бинарному формату типы должны были выложены
 

Активист

Активист
Команда форума
PHP:
$bin = pack( 'H*', 'abcdef12' );

var_dump(unpack( 'f', $bin ) );

/*
array(1) { [1]=> float(1.5133721576577E-27) }
*/
 

Активист

Активист
Команда форума
PHP:
$bin = pack( 'H*', '4D525454190420202001202001202020' );
var_dump(unpack( 'ddouble1/ddouble2', $bin) );
/*

array(2) {
["double1"]=>
float(5.9726435446551E-154)
["double2"]=>
float(6.0132936188542E-154)
}
*/
 

pavlik35

Новичок
PHP:
$bin = pack( 'H*', '4D525454190420202001202001202020' );
var_dump(unpack( 'ddouble1/ddouble2', $bin) );
/*

array(2) {
["double1"]=>
float(5.9726435446551E-154)
["double2"]=>
float(6.0132936188542E-154)
}
*/
Да, я только что попробовал без указания количества байт в unpack. Получается, если я укажу 8 байт - он мне выдает 8 раз по 8 байт, т.к. double это и есть 8 байт.
Но если мне надо следом вывести 10 байт вещественного числа?
 

Активист

Активист
Команда форума
вы понимаете вообще что такое бинарный формат данных? Из определения? double это 8 байт всегда, не больше и не меньше.

PHP:
$bin = pack( 'dd', 10.1, 20.5);
list($double1, $double2) = array_values(unpack( 'ddouble1/ddoble2', $bin));

print "<pre>";
print "Binary Data Length: ".strlen($bin)."\n";
print "Hex string: ".bin2hex($bin)."\n";
print "Double unpack: {$double1}, {$double2}";

/*
Binary Data Length: 16
Hex string: 33333333333324400000000000803440
Double unpack: 10.1, 20.5
*/
 

Активист

Активист
Команда форума
Если вам нужно распаковать число , например, на 12 байте, то используйте собстыенно fseek http://www.php.net/manual/ru/function.fseek.php или работайте с бинарнами данными как со строкой, если данные достаточно малы (например substr )
 

Активист

Активист
Команда форума
Вот пример:

PHP:
    $bin = pack( 'dd', 10.1, 20.5);
    list($double1, $double2) = array_values(unpack( 'ddouble1/ddoble2', $bin));
   
    print "<pre>";
    print "Binary Data Length: ".strlen($bin)."\n";
    print "Hex string: ".bin2hex($bin)."\n";
    print "Double unpack: {$double1}, {$double2}\n";
    print "Second double: ".unpack("ddouble", substr($bin, 8, 8))["double"]."\n";

/*

Binary Data Length: 16
Hex string: 33333333333324400000000000803440
Double unpack: 10.1, 20.5
Second double: 20.5
*/
 

pavlik35

Новичок
вы понимаете вообще что такое бинарный формат данных? Из определения? double это 8 байт всегда, не больше и не меньше.

PHP:
$bin = pack( 'dd', 10.1, 20.5);
list($double1, $double2) = array_values(unpack( 'ddouble1/ddoble2', $bin));

print "<pre>";
print "Binary Data Length: ".strlen($bin)."\n";
print "Hex string: ".bin2hex($bin)."\n";
print "Double unpack: {$double1}, {$double2}";

/*
Binary Data Length: 16
Hex string: 33333333333324400000000000803440
Double unpack: 10.1, 20.5
*/
Прекрасно понимаю.
Получается, если я укажу 8 байт - он мне выдает 8 раз по 8 байт, т.к. double это и есть 8 байт.
В мануале четко сказано, что после указания типа данных указывается КОЛИЧЕСТВО байтов для чтения.

PHP provides an unpack function which allows you to unpack any string, decomposing it into a set of fields. You need to tell it how many bytes you want each field to have.
Мне подумалось, что запись d8Header и должна вернуть 8 байт в виде double.

И тем не менее, если мне надо следом вывести 10 байт вещественного числа? Или пропустить их?
 

Активист

Активист
Команда форума
> В мануале четко сказано, что после указания типа данных указывается КОЛИЧЕСТВО байтов для чтения.
Где это написано??! Мануал прочитайте! Там не укажывается длинна в байтах, а указывается количество повторений!

PHP:
<?php
$bin = pack( 'dd', 10.1, 20.5); // тут 16 байт
var_dump(array_values(unpack( 'd2', $bin)));

/*
array(2) { [0]=> float(10.1) [1]=> float(20.5) }
*/
?>
> 10 байт вещественного числа
В PC нет числа из 10 байт. Разбирайтесь с основами. Если вы хотите прочитать что-либо (например double) с 10-го по 18 байт, то используйте substr или fseek
 
Сверху