【问题标题】:Convert 2 bytes to a number将 2 个字节转换为数字
【发布时间】:2011-02-09 06:06:31
【问题描述】:

我有一个控件,里面有一个字节数组。

不时有两个字节告诉我有关数组中未来项目数量的一些信息。

所以我可以举个例子:

... ... 项目 [4] = 7 项目 [5] = 0 ... ...

这个值显然是 7。

但是这个呢?

... ... 项目 [4] = 0 项目 [5] = 7 ... ...

你知道这相当于(作为一个普通的 int)吗?

我去二进制并认为它可能是 11100000000 等于 1792。但我不知道它是否真的是这样工作的(即它是否使用整个 8 项作为字节)。

有什么方法可以不经测试就知道这一点吗?

注意:我使用的是 C# 3.0 和 Visual Studio 2008

【问题讨论】:

  • 听起来您要求我们对一些序列化数据进行逆向工程。这会很棘手。您至少可以发布一些完整字节数组的示例以及它对应于三个或四个简单示例的内容。但是你为什么想知道这个呢?你想解决什么问题?
  • 我正在尝试破译 OpenNETCF 控件中 Signature 控件返回的字节数组,以便可以将其旋转 180 度。有关详细信息,请参阅此问题 stackoverflow.com/questions/2657388/…

标签: c# binary bytearray byte twos-complement


【解决方案1】:

BitConverter可以很方便地将两个字节转换成一个两字节整数值:

// assumes byte[] Item = someObject.GetBytes():
short num = BitConverter.ToInt16(Item, 4); // makes a short 
    // out of Item[4] and Item[5]

【讨论】:

  • @Macho Matt:如果您想对已经接受的答案发表评论,最好留下评论而不是编辑问题本身。此外,您的观点并不完全准确 - 计算机系统是大端还是小端无关紧要,只有最初创建字节数组的系统与运行.NET的系统具有不同的端序时才重要代码在这里。
  • 假设这两个字节的二进制表示的 MSB 是符号位 (1 = -ve, 0 = +ve)。如果不是这种情况,即。如果数字是无符号的,那么你需要使用它。 ushort num = BitConverter.ToUInt16(Item, 4)。另请记住,如果您的体系结构是小端序,那么索引 5 处的字节将作为第一个字节(最高有效字节)。阅读 reinventingthewheel.azurewebsites.net/TwosComplementTut.aspx 了解有关符号位的更多信息。
【解决方案2】:

一个两字节的数字有一个低字节和一个高字节。高字节的价值是低字节的 256 倍:

value = 256 * high + low;

因此,对于 high=0 和 low=7,该值为 7。但对于 high=7 和 low=0,该值变为 1792。

这当然假设数字是一个简单的 16 位整数。如果它是更花哨的东西,上面的就不够了。然后你需要更多关于数字是如何编码的知识,以便对其进行解码。

高低字节出现的顺序由字节流的endianness决定。在 big-endian 中,您会看到先高后低(在较低的地址),而在 little-endian 中则相反。

【讨论】:

  • 另外值得注意的是:(high << 8) | low
【解决方案3】:

您说“这个值显然是 7”,但这完全取决于编码。如果我们假设全角字节,那么在小端,是的; 7, 0 是 7。但在大端不是。

对于little-endian,你想要的是

int i = byte[i] | (byte[i+1] << 8);

对于大端:

int i = (byte[i] << 8) | byte[i+1];

但其他编码方案可用;例如,一些方案使用 7 位算术,第 8 位作为连续位。一些方案 (UTF-8) 将所有连续位放在第一个字节中(因此第一个字节只有有限的数据位空间),其余的 8 位在序列中。

【讨论】:

  • 好点。但是从用法上我可以看出该值为7(数组中还有7个坐标部分。
【解决方案4】:

如果您只是想将这两个字节以二进制格式彼此相邻,并查看该大数字在十进制中是什么,那么您需要使用以下代码:

if (BitConverter.IsLittleEndian)
{
    byte[] tempByteArray = new byte[2] { Item[5], Item[4] };
    ushort num = BitConverter.ToUInt16(tempByteArray, 0);
}
else
{
    ushort num = BitConverter.ToUInt16(Item, 4);
}

如果您在接受的答案中使用short num = BitConverter.ToInt16(Item, 4);,则假设这两个字节的第一位是符号位(1 = 负数,0 = 正数)。该答案还假设您使用的是大端系统。有关符号位的更多信息,请参阅this

【讨论】:

    【解决方案5】:

    如果这些字节是整数的“部分”,它的工作原理就是这样。但请注意,字节顺序是特定于平台的,并且还取决于整数的长度(16 位=2 字节,32 位=4 字节,...)

    【讨论】:

      【解决方案6】:

      如果 item[5] 是 MSB

      1. ushort 结果 = BitConverter.ToUInt16(new byte[2] { Item[5], Item[4] }, 0);

      2. int 结果 = 256 * Item[5] + Item[4];

      【讨论】:

        猜你喜欢
        • 2013-06-08
        • 2021-03-14
        • 1970-01-01
        • 2022-05-11
        • 1970-01-01
        • 2016-12-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多