PHP - unpack() uint8_t 和 uint16_t
Posted
技术标签:
【中文标题】PHP - unpack() uint8_t 和 uint16_t【英文标题】:PHP - unpack() uint8_t and uint16_t 【发布时间】:2014-12-18 09:25:13 【问题描述】:这是我在这里的第一个问题 - 所以我提前为任何错误道歉。
我目前从事一个项目,其中包括一个 C++ 程序,与运行 php 的 Web 服务器通信。
我已经多次使用 PHP 的解包/打包,但总是使用整个字节,通常是浮点数和 int32,以及填充字符串。但是现在,为了节省一些带宽,我们决定将 C 的输出“压缩”为更小的整数。
这是我的问题:
PHP 从 C 中获取的数据,大致如下(即 1 个字节):
(uint8_t)hc.OnOff << 1
| (uint8_t)hc.No1 << 2
| (uint8_t)hc.No2 << 3
| (uint8_t)hc.No3 << 4
| (uint8_t)hc.No4 << 5
| (uint16_t)hc.No5 << 6;
我尝试了很多方法来解压它。但我没有得到正确的结果。而且我知道在位方面我只是愚蠢的。 :)
我得到的最接近的是使用这样的东西:
$bit = unpack('C*', $bit);
$bit = $bit['1'];
$bin = decbin(ord($bit));
$bin = str_pad($bin, 8, 0, STR_PAD_LEFT);
但这仍然不是预期的结果。
还有其他的小窍门吗?
我为我糟糕的二进制知识道歉,我知道我必须阅读更多关于这个主题的内容。
【问题讨论】:
每个字段是否只是一个布尔值(如果是,为什么是uint8_t
和uint16_t
)?
好吧,C 代码不是我的工作,所以我问了我的同事。没有一点他们是不同的。其实是个错误。 :) - 是的,使用单个位布尔值。 :)
【参考方案1】:
假设每个值只是一个布尔值,并且没有昂贵的字符串操作:
$val = ord($bit);
$OnOff = (bool)($val & (1 << 1));
$No1 = (bool)($val & (1 << 2));
... etc
我注意到您显然没有使用零位?
【讨论】:
因为我必须稍后将值分配给数组(用于 DB 插入),所以您的方法对我来说比 @axiac 更好。但两者都很好。 :) 感谢您为我解决了两天的战斗。 :)【参考方案2】:pack()
/unpack()
应该是要走的路,但我有一个不同的 PHP 方法效果很好:将打包值的二进制表示生成为字符串,将其拆分为字符(每个字符将是 @987654323 @ 或1
),将它们放入相应的变量中:
list($No5, $No4, $No3, $No2, $No1, $OnOff, $ignore) =
str_split(
decbin($bit)
);
每个变量将接收一位。最后一个变量 ($ignore
) 接收您(没有)放在 C 代码包中的位 0
上的值。
【讨论】:
以上是关于PHP - unpack() uint8_t 和 uint16_t的主要内容,如果未能解决你的问题,请参考以下文章
Javascript Mismatch 中的 PHP Pack/Unpack 实现
为啥函数在 php 中以 @ 开头?像@unpack(xxx)? [复制]