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

如何在PHP中拆分二进制数据并将其转换为数字?,php,struct,binary,unpack,Php,Struct,Binary,Unpack,我正在从/dev/input/读取键盘事件。它们分别是5个数字,即24字节的little-endian格式 这是我当前的解决方案: $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",

我正在从
/dev/input/
读取键盘事件。它们分别是5个数字,即24字节的little-endian格式

这是我当前的解决方案:

$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;
};
其中,timeval是:

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);
?>


这只是一个基本的例子——我懒得检查endianness。

您可以将其作为单个值进行解包

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

只是为了帮助测试-您是否可以生成一些测试数据(不确定如何生成),为
fread($dev,24)
和预期的输出提供数据。另外,有关您正在使用的数据的更多详细信息可能会有所帮助。在这个结构定义中有太多的条件编译块,很难说最终结果会是什么。
Array
(
    [time1] => 1573746932
    [time2] => 878630
    [type] => 1
    [code] => 46
    [value] => 1
)