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

标签 perl bit

我正在读取数据流,准确地说是 64 字节。我想从传入数据的第 480 位开始读取 16 位。不幸的是,我不知道传入的数据类型是什么,它是一堆随机字符/框。将其作为无符号短整型 (v) 读取,得到我要查找的数字,在本例中为 13。

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

这会导致 $satt_id == 13,即 00000000 00001101。

如果我将数据提取为 16 位(b 或 B),则该字符串不会反射(reflect) 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 无关,但这在另一个实用程序中困扰着我。我只是通过交换枚举名称中的值来承认。它有效,只是当位数高于 4(16 个不同的值)时不太可行。

谢谢!

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

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

最佳答案

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

0b0000000000001101

存储为

0b00001101 0b00000000

这就是你得到的。


Should I just use little-endian b and then reverse?

没有。如果您将数字转换为文本表示形式(二进制),您可能会做一些不正确的事情。

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

sprintf("%16b", $num)

关于perl - 不寻常的无符号短位交换字节顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61623544/

相关文章:

perl - 是否有类似引号的内插单词列表运算符?

命名子例程中的 perl 匿名子例程

perl - 为什么安装 Scrappy 时 CPAN 安装失败?

java - 如何使用java以位方式保存文件?

c - unsigned int 结合 unsigned char 的小位操作问题

linux - 将主脚本变量传递到 Perl 模块

perl - Moo、惰性属性和默认/强制调用

c++ - 分解 LPARAM 变量并查看位组

c 位操作操作不乘以字符

c - 得到两个无符号整数相乘的高 32 位 (HW)