【问题标题】:Unusual unsigned short to bits swapping byte order不寻常的无符号短到位交换字节顺序
【发布时间】:2020-05-05 21:39:22
【问题描述】:

我正在读取数据流,确切地说是 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:基本上我正在尝试制作一种用户友好的方法来编辑来自数据流的消息。正如我在 cmets 中提到的,如果我想编辑从 0 到 1 的单个位(在消息中表示真/假),我不希望用户担心编辑接收到的八位字节数据,只需从真/假下拉列表中选择。

【问题讨论】:

  • 为什么还要字节的二进制表示???
  • ikegami - 有没有更好的方法从流中更改/读取 2 位和 1 位“数据”?
  • 您无法从流中读取位;读取是按照八位字节(8 位)完成的。 pack/unpack 类似地面向八位字节。
  • 好的,是的,我同意这一点。数据以八位字节流式传输。但是假设第 7 位是一个真/假枚举。将其从 0 更改为 1(假为真)的最佳方法是什么?按八位字节解包,转换为二进制,更改,转换回八位字节,然后重新打包为八位字节?
  • @BenWest 如果你要修改它,你可能想使用perldoc.perl.org/functions/vec.html

标签: perl bit


【解决方案1】:

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

0b0000000000001101

存储为

0b00001101 0b00000000

这就是你得到的。


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

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

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

sprintf("%16b", $num)

【讨论】:

  • 我想我需要了解一下位存储。 0b00001101 0b00000000 == 10110000 00000000 是怎么回事?
  • 不是。您使用的符号不一致。您将首先显示其中一些数字的最低有效位,然后首先显示最高有效位。在我编程的 30 年中,我从未遇到过任何人首先使用最低有效位,所以我重复一遍(首先使用最高有效位): 0b00001101 0b00000000 是 16 位整数十三(13, 0xD , 0b1101) 使用 LE 字节顺序存储。 0b00001101 | (0b00000000
  • 啊,看来我首先混淆了 LE/BE 字节顺序和 LS/MS 位。所以正确的数据是以 LE 字节顺序的 MS 位在前,即 B16(MS 位在前),而不是 b16(LS 位在前),但无论如何它都是 LE 字节顺序。
  • LE 字节顺序和 MS 位顺序在您给出的示例中更有意义。谢谢!
  • 请记住,在内存中,您有两个字节按某种顺序排列。没有位;所以位顺序是表示数字时使用的纯人为概念。就像将 12 写成 12 而不是 21 纯粹是惯例。关键是在讨论数字的存储方式时,只有 LE 与 BE 字节顺序很重要,而不是位顺序。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-07
  • 1970-01-01
  • 1970-01-01
  • 2013-08-19
  • 1970-01-01
  • 2015-10-21
相关资源
最近更新 更多