Это мой первый вопрос здесь — поэтому я заранее прошу прощения за любые ошибки.
В настоящее время я работаю над проектом, который включает в себя программу на 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);
Но это все еще не ожидаемый результат.
У кого-нибудь есть другие советы?
И я прошу прощения за мои плохие двоичные знания, я знаю, что я должен прочитать еще немного по этой теме.
Предполагая, что каждое значение является просто логическим битом без дорогостоящих строковых операций:
$val = ord($bit);
$OnOff = (bool)($val & (1 << 1));
$No1 = (bool)($val & (1 << 2));
... etc
Я заметил, что вы, очевидно, не используете бит ноль?
pack()
/unpack()
должен быть путь, но у меня есть другой подход PHP, который работает хорошо: создать двоичное представление упакованного значения в виде строки, разделить его на символы (каждый символ будет 0
или же 1
), поместите их в соответствующие переменные:
list($No5, $No4, $No3, $No2, $No1, $OnOff, $ignore) =
str_split(
decbin($bit)
);
Каждая переменная получит один бит. Последняя переменная ($ignore
) получает значение, которое вы (не) ставили на бит 0
в упаковке в коде C.