这个问题与以下内容有关: C# How to extract bytes from byte array? With known starting byte
我有“100字节byte []”,它由几个随机出现在较大字节中的“14字节byte []”组成。
我的较小字节[]以(字节)0x55开头,后来结束16字节
我正在使用代码:
byte[] results = new byte[16];
int index = Array.IndexOf(readBuffer, (byte)0x55, 2);
Array.Copy(readBuffer, index, results, 0, 16);
但有了这个,我只得到第一次出现的小字节[]。
如何获得所有较小的byte []块?
PS:我正在使用.Net Micro Framework
答案 0 :(得分:1)
我假设你的消息由一个起始cookie字节0x55
,14个字节的实际数据和1个校验和字节组成(因为你可以互换地使用14和16个字节)。随机发生子阵列有意义的唯一方法是在结尾处有一个校验和值,以确认你的起始字节实际上是一个有效的cookie(而不是一个数据字节)。
(更新后修改)
因此,您的实际数据为0x55 + 1syncbyte + 2 checksum + 12 databytes
,这意味着您的函数应该:
从索引i
= 0开始,并在i + 15
<时重复输入长度:
i
处的Cookie。
i
并重新开始。i + 1
处的字节。
i
并重新开始。i + 2
/ i + 3
读取16位校验和,计算实际数据校验和并进行比较。
i
并重新开始。i + 4
复制到i + 15
到一个大小为12的段。
您可以使用0x55
跳转到第一次出现Array.IndexOf
,但由于您无论如何都需要跟踪索引,您可以自己检查并简化代码(算法复杂度与O(n)
)相同。
对此进行编码的一种方法是:
private static IEnumerable<byte[]> EnumerateSegments(byte[] input)
{
var i = 0;
while (i + 15 < input.Length)
{
// check if it starts with 'sync' bytes
// (not sure which is the second one, though?)
var cookie = input[i];
if (input[i] != 0x55 || input[i + 1] != 0xAA)
{
i++;
continue;
}
// get the 16-bit checksum
// (check if this is the correct endian, i.e. you
// might need to swap bytes)
var receivedChecksum = (input[i + 2] << 8) | (input[i + 3]);
// calculate the checksum over data only
var calculatedChecksum = CalculateChecksum(input, i + 4, 12);
if (receivedChecksum != calculatedChecksum)
{
i++;
continue;
}
// if we're here, data should be valid, so the last
// thing left to do is to copy the data into the subarray
var segment = new byte[12];
Array.Copy(input, i + 4, segment, 0, 12);
yield return segment;
// skip this segment
i += 16;
}
}
您可以在foreach
循环中使用它来迭代细分:
foreach (var segment in EnumerateSegments(input))
{
ProcessSegment(segment);
}
如果您想多次迭代元素,也可以获得一个段列表:
List<byte[]> listOfSegments = EnumerateSegments(input).ToList();
由于您不熟悉C#(通常是编程),我建议您在方法中放置一个断点,然后一步一步地了解发生了什么。