我收到一个包含字节数组的数据包,我必须从中获取一些整数值。这是文档的一部分。有人能帮助我吗?
这是一个 4 字节的数组。
年从 1990 到 2052(6 位),月从 1 到 12(4 位),日从 1 到 31(5 位),小时从 0 到 23(5 位),分钟从 0 到 59(6 位),秒从 0 到 59(6 位) 默认值:2000 年 1 月 1 日,12:00:00
消息的格式是小端。
我收到一个包含字节数组的数据包,我必须从中获取一些整数值。这是文档的一部分。有人能帮助我吗?
这是一个 4 字节的数组。
年从 1990 到 2052(6 位),月从 1 到 12(4 位),日从 1 到 31(5 位),小时从 0 到 23(5 位),分钟从 0 到 59(6 位),秒从 0 到 59(6 位) 默认值:2000 年 1 月 1 日,12:00:00
消息的格式是小端。
您需要的是一些按位运算。首先,用字节构造一个 int :
int n = b[0] | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
然后,将 int 切成组件。现在,您的问题没有指定字段的方向是从右到左还是从左到右。该问题与字节顺序有关,但不完全相同。所以让我们假设字段从左到右。
良好的感觉建议从左到右。这样可以比较时间值的整数表示 - 年位的重要性大于月位等,因此当您比较对应于两个时间点的整数时,您会得到按时间顺序正确的结果。
这是给你的心理图像。这是一个整数变量,由位组成:
f e d c b a 9 8 7 6 5 4 3 2 1 0
-----
offset is 6, length is 3
让我们定义一个函数,该函数在给定偏移量(以位为单位)处从 int 获取任意块,并具有给定的长度(以位为单位)。
int bits(int n, int offset, int length)
{
//shift the bits rightward, so that the desired chunk is at the right end
n = n >> (31 - offset - length);
//prepare a mask where only the rightmost `length` bits are 1's
int mask = ~(-1 << length);
//zero out all bits but the right chunk
return n & mask;
}
本来可以是单行的,但我想让它有点指导意义。通过手动为每个块指定移位因子和掩码,以下答案中的人们有效地内联了此函数。
现在让我们分解。假设 n 来自最上面的片段:
int year = bits(n, 0, 6),
month = bits(n, 6, 4),
day = bits(n, 10, 5),
hour = bits(n, 15, 5),
min = bits(n, 20, 6),
sec = bits(n, 26, 6);
我们通过将先前字段的总长度组合在一起来获得偏移量的值。这是在字段从左到右的假设下;如果他们反过来,偏移值会不同。
这有意义吗?
编辑:如果位块从右到左,那么它是这样的:
int sec = bits(n, 0, 6),
min = bits(n, 6, 6),
hour = bits(n, 12, 5),
day = bits(n, 17, 5),
month = bits(n, 22, 4),
year = bits(n, 26, 6);
首先,我将其转换为整数:
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
int timestamp = ByteBuffer.wrap(byte_array).order(ByteOrder.LITTLE_ENDIAN).getInt();
接下来,我将其拆开:
int yearCode = (timestamp >> 26) & 0b111111;
int monthCode = (timestamp >> 22) & 0b1111;
int dayCode = (timestamp >> 17) & 0b11111;
int hourCode = (timestamp >> 12) & 0b11111;
int minCode = (timestamp >> 6) & 0b111111;
int secCode = (timestamp >> 0) & 0b111111;
第一行的掩蔽和最后一行的移位不是绝对必要的,但为了清楚起见,将其保留。
最后一步是将 1900 添加到 中yearCode
,您就完成了!
假设您有 java 7,您应该能够将年份读取为
int year = 1990
+ ((b[0] & 0b1000_0000) << 5)
+ ((b[0] & 0b0100_0000) << 4)
+ ((b[0] & 0b0010_0000) << 3)
+ ((b[0] & 0b0001_0000) << 2)
+ ((b[0] & 0b0000_1000) << 1)
+ ((b[0] & 0b0000_0100));
月份为
int month = 1
+ ((b[0] & 0b1000_0010) << 3)
+ ((b[0] & 0b0100_0001) << 2)
+ ((b[1] & 0b1000_0000) << 1)
+ ((b[1] & 0b0100_0000));
我让你以同样的方式做其他整数。
我没有java7,现在不能测试,希望没有错。字节的顺序也可能是相反的。