异常的无符号短到位交换字节顺序

时间:2020-05-05 21:39:22

标签: perl bit

我正在读取数据流,确切地说是64个字节。我想从传入数据的第480位开始读取16位。不幸的是,我不知道传入的数据类型是什么,它是一堆随机字符/框。将其读为无符号的短(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位。我应该只使用little-endian b然后反转吗?更改数据后,将其反向恢复为原始顺序,然后将其打包为b?

完全独立且与perl不相关,但这在另一个实用程序中困扰着我。我只是通过交换Enum名称中的值来让步。它起作用了,但是当位数超过4(16个不同的值)时,并不是很可行。

谢谢!

编辑:我猜这只是与二进制表示法有关?显然是从右边开始的?因此,如果您从右到左阅读,$ satt_idb是正确的。因此,要使其更加用户友好,只需反转,更改,然后再次反转并重新打包?

EDIT2:基本上,我正在尝试制作一种用户友好的方法来编辑通过数据流发送的消息。正如我在评论中提到的,如果我想编辑一个从0到1的单个位(消息中表示真/假的东西),我不希望用户担心编辑接收到的数据八位字节,只需从true / false下拉菜单中选择即可。

1 个答案:

答案 0 :(得分:4)

如果与v一起使用,则表示数据在little-endian byte order中,这意味着

0b0000000000001101

存储为

0b00001101 0b00000000

这就是你所得到的。


我应该只使用little-endian b然后反转吗?

不。如果要将数字转换为文本表示形式(二进制),则可能做错了。

如果您确实想要数字的二进制表示形式,则可以使用

sprintf("%16b", $num)
相关问题