php pack: проблемы с типами данных и проверка моих результатов

Я начинаю PHP, и моя задача – создавать команды, которые позже будут отправляться через UDP на устройство. Выполнение: OSX, PHP 5.5.3.8 Для создания двоичных данных я использую «pack». Вот пример моего кода:

<?php $in_1 = 0x3100; $in_2 = 0031; echo "Inputs: " . $in_1 . "\t" . $in_2; $bin = pack("v*", $in_1, $in_2); echo "\nlength: ". strlen($bin); printf ("\npacked result: %x \n",$bin); printf("HEX result %h\n", $bin); file_put_contents("ausgabe.log", $bin, FILE_APPEND); ?> 

вывод в моем терминале:

 Inputs: 12544 25 length: 4 packed result: 0 HEX result 

Интересно, номер 25 для $ in_2. Если я назначу 0x0031 в $ in_2, результат будет 49. Что здесь не так?

Кстати: Моя конечная цель – построить двоичные команды, которые равны 12 байтам в такой схеме (десятичные значения как комментарии в каждой строке):

 function set_routing_item ($in_ch, $out_ch, $on_off, $seq) { $command = toggle_two_bytes(37); // 37 --> 0x2500 $status = 0x0000; // 0 --> 0x0000 $pos = 4; // 4= route item $channel_1 = $in_ch; // 3 $channel_2 = $out_ch; // 6 $preset_no = 0xff; // 255 $value = $on_off; // 33145 $seq = $seq; // 35 // implement building of command using pack here } 

Результат в этом случае (шестнадцатеричный) должен выглядеть так: 25 00 00 00 04 03 06 FF 79 81 23 00

Благодаря!

Я придумал это, но это не лучший способ сделать это, правильные побитовые операции будут быстрее.

Я использую sprintf с спецификатором формата %x , который преобразует значение в шестнадцатеричное значение.

Каждая спецификация преобразования состоит из знака процента (%)

Вы увидите, что я использую %02x и %04x

  • 0 – левая панель с нулями
  • 2 или 4 – Ширина, минимальное количество символов для печати.
  • x – Спецификатор для шестнадцатеричного, используйте X для прописных букв.

Код:

 <?php function toggle_two_bytes ($two_bytes) { $two_bytes = $two_bytes & 0xffff; // limit size to 2 Bytes $high = ($two_bytes << 8); // bit shift $low = ($two_bytes >> 8); $ret = ($high | $low); // OR $ret = $ret & 0xffff; // limit (again) to two bytes return ($ret); } function set_routing_item ($in_ch, $out_ch, $on_off, $seq) { $str = ''; $command = toggle_two_bytes(37); $str .= sprintf('%04X', $command); $status = 0x0000; $str .= sprintf('%04X', $status); $pos = 4; $str .= sprintf('%02X', $pos); $str .= sprintf('%02X', $in_ch); $str .= sprintf('%02X', $out_ch); $preset_no = 0xFF; $str .= sprintf('%02X', $preset_no); $value = toggle_two_bytes($on_off); $str .= sprintf('%04X', $value); $seq = toggle_two_bytes($seq); $str .= sprintf('%04X', $seq); for ($i = 0; $i < strlen($str) - 1; $i += 2) { echo $str[$i] . $str[$i+1] . ' '; } } echo set_routing_item(3, 6, 33145, 35) . PHP_EOL; 

Вывод:

 25 00 00 00 04 03 06 FF 79 81 23 00 

Демо: https://eval.in/793695

Извините за мой плохой отформатированный ответ. Вот запрошенный код:

 // toggle higher and lower byte of a two-byte short variable function toggle_two_bytes ($two_bytes)` { $two_bytes = $two_bytes & 0xffff; // limit size to 2 Bytes $high = ($two_bytes << 8); // bit shift $low = ($two_bytes >> 8); $ret = ($high | $low); // OR $ret = $ret & 0xffff; // limit (again) to two bytes return ($ret); } 

Я узнал, что с пакетом ('v', …) это больше не нужно.