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



我正在读取一个数据流,确切地说是64字节。我想从输入数据的第480位开始读取16位。不幸的是,我不知道传入的数据类型是什么,它是一堆随机字符/框。把它读成一个无符号短(v(,我得到了我要找的数字,在这个例子中是13。

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

这导致$satt_id==13,即0000000000001101。

如果我将数据提取为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位,这将相对容易。我应该只使用小endian b然后反转吗?更改数据后,将其反转为原始顺序,然后将其打包为b?

完全独立,与perl无关,但这在另一个实用程序中困扰着我。我只是通过交换Enum指定中的值来让步。它起作用了,只是当比特数量超过4(16个不同的值(时就不太可行了。

谢谢!

编辑:我猜这只是和二进制记数法有关吧?显然是从右边开始的?因此,如果从右到左阅读,$satt_idb是正确的。所以,为了让它更方便用户,只需反转、更改,然后再次反转并重新打包?

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

如果它与v一起工作,则意味着数据以小端字节顺序排列,这意味着

0b0000000000001101

存储为

0b00001101 0b00000000

这就是你得到的。


我应该只使用小端序b然后反转吗

否。如果您将数字转换为文本表示形式(二进制(,那么您可能做了不正确的事情。

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

sprintf("%16b", $num)

最新更新