如何拆分二进制数据并将其转换为PHP中的数字?

How to split binary data and convert it into numbers in PHP?

我正在读取来自 /dev/input/ 的键盘事件。这些是 input_event structs,分别是小端格式的 24 个字节的五个数字。

这是我目前的解决方案:

$hex = bin2hex(fread($dev, 24));
$time = floatval(unpack("Q", (pack('H*', substr($hex, 0, 16))))[1].".".unpack("Q", (pack('H*', substr($hex, 16, 16))))[1]);
$type = intval(unpack("S", (pack('H*', substr($hex, 32, 4))))[1]);
$code = intval(unpack("S", (pack('H*', substr($hex, 36, 4))))[1]);
$value = intval(unpack("l", (pack('H*', substr($hex, 40, 8))))[1]);

必须 是在 PHP 中执行此操作的更有效方法。任何人?布勒?

更新:

Blob 示例为:

$raw = hex2bin("f478cd5d0000000026680d000000000001002e0001000000");

这导致:

$time = 1573746932.8786;
$type = 1;
$code = 46;
$value = 1;

实际结构如下所示:

struct input_event {
    timeval time;
    __u16 type;
    __u16 code;
    __s32 value;
};

时间间隔是:

struct timeval {
    __u64 sec;
    __u64 usec;
}

据我所知,没有真正的浮点值:

 (gdb) ptype struct input_event
 type = struct input_event {
     struct timeval time;
     __u16 type;
     __u16 code;
     __s32 value;
 }

 (gdb) ptype struct timeval
 type = struct timeval {
     __time_t tv_sec;
     __suseconds_t tv_usec;
 }

 (gdb) ptype __time_t
 type = long

 (gdb) ptype __suseconds_t
 type = long

 (gdb) ptype __u16
 type = unsigned short

 (gdb) ptype __u16
 type = unsigned short

 (gdb) ptype __s32
 type = int

既然是这种情况,您只需做一些二进制工作即可:

<?
// Converts your data to byte array
$d = unpack('C*', fread($dev, 24));

// Calculate whatever you desire ...
$tv_sec = ($d[1]<<56) + ($d[2]<<48) + ($d[3]<<40) + ($d[4]<<32) + ($d[5]<<24) + ($d[6]<<16) + ($d[7]<<8) + ($d[8]<<0);
?>

这只是一个基本示例 - 我懒得检查字节顺序。

您可以将其解包为单个值。

<?php
$raw = fread($dev, 24);
$data = unpack("Ptime1/Ptime2/vtype/vcode/Vvalue", $raw);
print_r($data);

输出:

Array
(
    [time1] => 1573746932
    [time2] => 878630
    [type] => 1
    [code] => 46
    [value] => 1
)