Я начинаю 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', …) это больше не нужно.