【问题标题】:How to interpret hex number byte array from left shift binary sum?如何从左移二进制和解释十六进制数字节数组?
【发布时间】:2016-09-10 17:08:35
【问题描述】:

我的 android 应用程序正在接收从 C# 应用程序发送的数据字节数组。我需要解释这些字节。

在 C# 应用程序中,表单中有 16 个复选框(Bit0 到 Bit15),代码显示了对这些复选框结果的处理。

ushort flag = (ushort)(
                (Bit0.Checked ? (1 << 0) : (0)) +
                (Bit1.Checked ? (1 << 1) : (0)) +
                (Bit2.Checked ? (1 << 2) : (0)) +
                (Bit3.Checked ? (1 << 3) : (0)) +
                (Bit4.Checked ? (1 << 4) : (0)) +
                (Bit5.Checked ? (1 << 5) : (0)) +
                (Bit6.Checked ? (1 << 6) : (0)) +
                (Bit7.Checked ? (1 << 7) : (0)) +
                (Bit8.Checked ? (1 << 8) : (0)) +
                (Bit9.Checked ? (1 << 9) : (0)) +
                (Bit10.Checked ? (1 << 10) : (0)) +
                (Bit11.Checked ? (1 << 11) : (0)) +
                (Bit12.Checked ? (1 << 12) : (0)) +
                (Bit13.Checked ? (1 << 13) : (0)) +
                (Bit14.Checked ? (1 << 14) : (0)) +
                (Bit15.Checked ? (1 << 15) : (0)));

flag 被传递给下面描述的函数,然后被发送到我的 Android 应用程序。

    public static void setFlag(List<Byte> data, ushort flag)
    {
        for (int i = 0; i < 2; i++)
        {
            int t = flag >> (i * 8);
            data.Add((byte)(t & 0x00FF));
        }
    }

在Android应用程序中,数据以4字节数组的形式接收,然后转换为十进制

public String bytesToAscii(byte[] data) {
    String str = new String(data);
    return str.trim();
}

// This returns the decimal
Integer.parseInt(bytesToAscii(flag), 16)

例如,当在 C# 应用程序中检查 Bit13 时; Andriod 应用程序接收一个 4 字节的数组,代表十六进制数:

flag[0] = 0x30;
flag[1] = 0x30;
flag[2] = 0x32;
flag[3] = 0x30;

先转换成0020再转换成十进制:

Integer.parseInt(bytesToAscii(flag), 16); // 32

我需要解析 32 来确定 Bit13 被选中。 Bit13 只是 32 的一个例子。我需要弄清楚选择了哪个或多个 Bit(0 到 15)。

【问题讨论】:

  • 为什么接收的数据是 4 字节的数组而不是 2 字节的数组?
  • 为什么要乘以 8?如果您有两个字节,则 data[0]
  • @JornVernee 他正在添加 2 个字节(0 和 1) - 但我没有得到转换的整个过程......
  • 我不知道我收到 4 个字节而不是 2 个字节的原因。我不完全理解 C# 部分,因为它是由其他开发人员开发的。幸运的是,我得到了他们的源代码。根据setFlag(),它是2字节,但在他们的系统文档中,大小长度是N * 2字节。这就是我收到 4 个字节的原因。

标签: java c# android hex byte


【解决方案1】:

要检查是否设置了某个位,您可以对该位进行按位与。然后检查结果是否等于 0。如果不是,则该位已设置。

例如

00100110
00000010     // checks the second bit
-------- &
00000010     // result != 0, so the bit was set

char 是无符号的 16 位,因此您可以使用它来存储结果。

0020 几乎是对的,但是字节颠倒了(00 20,Bit13 应该是20 00)。

byte[] flag = new byte[4];      
flag[0] = 0x30;
flag[1] = 0x30;
flag[2] = 0x32;
flag[3] = 0x30;

// Bytes to char, using the 'oversized' short so the numbers won't be out of range
short b1 = Short.parseShort(new String(new byte[]{flag[0], flag[1]}), 16);
short b2 = Short.parseShort(new String(new byte[]{flag[2], flag[3]}), 16);
char i = (char) (b1 | (b2 << 8));

// Print contents as binary string
System.out.println(String.format("%16s", Integer.toBinaryString(i)).replace(' ', '0'));

// Output: 0010000000000000

// Check if 14'th bit is set (at index 13)
boolean isSet = ((i & (1 << 13)) != 0);

System.out.println(isSet); // true

您可以使用该方法检查每个位。只需将13 替换为您要检查的索引即可。


我在这里使用char,因为它会打印得更好一些。您可以使用short,但无论何时将其转换为int(这可能会隐式发生),如果设置了最高有效位,则该值将用1 填充,因为它是带符号的 类型。 charunsigned 但是,它没有这种行为。

【讨论】:

  • 根据我的示例0x30 0x30 0x32 0x30,唯一设置的位是Bit13。为什么你的结果中有很多位 1
  • @Sithu 这只是一个例子......但我终于弄清楚了你的转换应该如何工作。查看更新的答案。
  • 谢谢。这几乎行得通。但是,当我打开所有位时,该值是 FFFF 相当于 0x46 0x46 0x46 0x46 并抛出 java.lang.NumberFormatException: Value out of range. Value:"FFFF" Radix:16 at java.lang.Short.parseShort(Unknown Source)FF7F 在除 Bit15 之外的所有位都打开时出现相同的错误。
  • @Sithu 注意 - 如果只有第 15 位未设置,则值为 0xFF7F - 交换字节 - 当前位结构将是 [7-0][15-8]...
  • 并防止java.lang.NumberFormatExceptionshort 更改为intlong...
猜你喜欢
  • 2023-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-08
  • 1970-01-01
  • 2014-10-30
  • 2022-11-16
相关资源
最近更新 更多