Search code examples
phpc++unpackuint

PHP - unpack() uint8_t and uint16_t


This is my first question here - so I apologize in advance for any errors.

I currently work on a project, which includes a C++ program, communicating with a web server running PHP.

I've used PHP's unpack/pack many times, but always with whole bytes, and usually float and int32, and padded strings. But now, to save some bandwidth, we've decided to "compress" the output from C to smaller integers.

Here is my problem:

The data PHP gets from C, looks roughly like this (that 1 byte):

(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;

I've tried to unpack this in many ways. But I don't get proper results. And I know I am just plane stupid when it comes to bits. :)

The closest I've gotten is using something like this:

$bit = unpack('C*', $bit);
$bit = $bit['1'];
$bin = decbin(ord($bit));
$bin = str_pad($bin, 8, 0, STR_PAD_LEFT);

But It's still not the expected result.

Has anyone got some other tips?

And I do apologize for my poor binary knowledge, I do know I have to read some more up on this topic.


Solution

  • Assuming that each value is just a single bit boolean, and without expensive string operations:

    $val = ord($bit);
    
    $OnOff = (bool)($val & (1 << 1));
    $No1   = (bool)($val & (1 << 2));
    ... etc
    

    I note that you're apparently not using bit zero?