Необычное беззнаковое замыкание на биты, меняющие порядок байтов - PullRequest
2 голосов
/ 06 мая 2020

Я читаю поток данных, точнее 64 байта. Я хочу читать 16 бит, начиная с 480-го бита входящих данных. К сожалению, я не знаю, что это за тип входящих данных, это набор случайных символов / блоков. Читая его как unsigned short (v), я получаю искомое число, которое в этом примере равно 13.

my $satt_id = unpack("x60v1"), $msgdata); #$satt_id == 13

В результате получается $ satt_id == 13, что равно 00000000 00001101.

Если я извлечу данные как 16 бит (b или B), строка не будет отражать значение 13, а будет переставлена ​​местами или перевернута.

my $satt_idb = unpack("x60b16", $msgdata); #satt_idb == "10110000 00000000"
my $satt_idB = unpack("x60B16", $msgdata); #satt_idB == "00001101 00000000"

Почему это происходит? Я хочу изменить данные и повторно отправить сообщение, что было бы относительно легко, если бы все элементы сообщения были одинакового размера (16 бит, просто упакуйте обратно, когда оно было распаковано), но некоторые из них 6, 4, 2 и 1 бит. Должен ли я просто использовать прямой порядок байтов b, а затем наоборот? После изменения данных переверните их обратно в исходный порядок, а затем упакуйте обратно как b?

Полностью отдельный и не perl связанный, но это не давало мне покоя в другой утилите. Я просто согласился, поменяв местами значения в обозначении Enum. Это сработало, просто было не очень жизнеспособно, когда количество бит стало выше 4 (16 различных значений).

Спасибо!

РЕДАКТИРОВАТЬ: Я предполагаю, что это связано с двоичным кодом обозначения? Видимо начинается справа? Итак, $ satt_idb верен, если читать справа налево. Итак, чтобы сделать его более удобным для пользователя, просто переверните, измените, затем снова переверните и снова упакуйте?

EDIT2: В основном я пытаюсь сделать удобный метод редактирования сообщений, поступающих через поток данных. Как я уже упоминал в комментариях, если я хочу отредактировать один бит с 0 до 1 (который в сообщении представляет что-то как истина / ложь), я не хочу, чтобы пользователю приходилось беспокоиться о редактировании октета полученных данных. , просто выберите из раскрывающегося списка истинное / ложное значение.

1 Ответ

4 голосов
/ 06 мая 2020

Если он работает с v, это означает, что данные находятся в младшем байтовом порядке , что означает, что

0b0000000000001101

хранится как

0b00001101 0b00000000

это то, что у вас есть.


Должен ли я просто использовать прямой порядок байтов b, а затем обратный?

Нет. Вы, вероятно, делаете что-то неправильно, если конвертируете числа в текстовое представление (двоичное).

Если вам каким-то образом нужно двоичное представление числа, вы можете использовать

sprintf("%16b", $num)
...