PHP — распаковать () uint8_t и uint16_t

Это мой первый вопрос здесь — поэтому я заранее прошу прощения за любые ошибки.

В настоящее время я работаю над проектом, который включает в себя программу на C ++, взаимодействующую с веб-сервером под управлением PHP.

Я использовал распаковку / упаковку 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);

Но это все еще не ожидаемый результат.

У кого-нибудь есть другие советы?

И я прошу прощения за мои плохие двоичные знания, я знаю, что я должен прочитать еще немного по этой теме.

1

Решение

Предполагая, что каждое значение является просто логическим битом без дорогостоящих строковых операций:

$val = ord($bit);

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

Я заметил, что вы, очевидно, не используете бит ноль?

1

Другие решения

pack()/unpack() должен быть путь, но у меня есть другой подход PHP, который работает хорошо: создать двоичное представление упакованного значения в виде строки, разделить его на символы (каждый символ будет 0 или же 1), поместите их в соответствующие переменные:

list($No5, $No4, $No3, $No2, $No1, $OnOff, $ignore) =
str_split(
decbin($bit)
);

Каждая переменная получит один бит. Последняя переменная ($ignore) получает значение, которое вы (не) ставили на бит 0 в упаковке в коде C.

0

По вопросам рекламы [email protected]