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

问题描述 投票:0回答:1

我正在读取一个数据流,准确的说是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位。我是不是应该直接用小二进制b,然后反转?改完数据后反转回原来的顺序,然后再打包成b?

完全是分开的,与perl无关,但这在另一个实用程序中困扰着我。我只是通过交换Enum指定中的值来认输。它工作了,只是当位数超过4(16个不同的值)时,就不太可行了。

谢谢!

EDIT:我猜这只是和二进制符号有关?显然是从右边开始的?所以$satt_idb是正确的,如果你从右往左读。所以为了更方便用户使用,就把它反过来,改动,然后再反过来,重新打包?

EDIT2: 基本上我是想做一个用户友好的方法来编辑通过数据流传来的消息。正如我在评论中提到的,如果我想编辑从0到1的单个位(在消息中表示为truefalse的东西),我不想让用户担心编辑收到的八位组数据,只需从truefalse的下拉列表中选择即可。

perl bit
1个回答
4
投票

如果能用 v意思是数据在 小字节顺序这意味着

0b0000000000001101

存储为

0b00001101 0b00000000

这是你得到的。


我应该只用小写字母b,然后反过来吗?

不,如果你将数字转换为文本表示(二进制),你很可能做了一些不正确的事情。

如果你确实想要数字的二进制表示,你可以使用

sprintf("%16b", $num)
© www.soinside.com 2019 - 2024. All rights reserved.