我正在尝试在另一个字节数组byte[]
内找到一个字节数组byte[]
。
问题:如何从头到尾搜索另一个字节数组中的字节数组?
此链接是我正在制作的代码的参考 c# How to Continuously find a byte array inside a byte array?
编辑:我需要将此代码转换为在另一个反向的字节数组中搜索字节。
indexPos = SearchBytes(input, find, indexPos);
Console.WriteLine("Found at " + indexPos);
indexPos += find.Length;
更新:当我点击按钮时,索引需要搜索如下:11,6 1
以下代码是我需要从头到尾搜索的内容:
byte[] input = { 0, 1, 1, 1, 5, 6, 1, 1, 1, 7, 8, 1, 1, 1 };
byte[] find = { 1, 1, 1 };
int indexPos = 0;
private void button1_Click(object sender, EventArgs e)
{
indexPos = SearchBytes(input, find, indexPos);
Console.WriteLine("Found at " + indexPos);
indexPos += find.Length;
}
public int SearchBytes(byte[] haystack, byte[] needle, int start_index)
{
int len = needle.Length;
int limit = haystack.Length - len;
for (int i = start_index; i <= limit; i++)
{
int k = 0;
for (; k < len; k++)
{
if (needle[k] != haystack[i + k]) break;
}
if (k == len) return i;
}
return -1;
}
答案 0 :(得分:2)
您可以使用LINQ
查询以及Array.Reverse
来帮助您。
修改强>
要查找多个字节的模式,您需要像这样更新LINQ
查询
byte[] input = { 0, 1, 1, 1, 5, 6, 1, 1, 1, 7, 8, 1, 1, 1 };
byte[] find = { 1, 1, 1 };
int indexNow = 0;
int findLength = find.Length;
int[] indexes = (from i in input
let index = indexNow++
where index <= input.Length - findLength //cannot exceeds this on the search
let compared = input.Skip(index).Take(findLength)
where Enumerable.SequenceEqual(find, compared)
select index).Reverse().ToArray();
您indexes
的结果将是11,6,1
,如您所愿。
要使用函数,只需将上面使用的所有查询和输入放到返回indexes
的函数中。
public int[] SearchBytes(byte[] input, byte[] find){
int indexNow = 0;
return (from i in input
let index = indexNow++
where index <= input.Length - find.Length//cannot exceeds this on the search
let compared = input.Skip(index).Take(find.Length)
where Enumerable.SequenceEqual(find, compared)
select index).Reverse().ToArray();
}
<强>原始强>
假设您只定义了评论中讨论的一个byte
needle
,您可以这样做:
byte[] input = { 0, 1, 1, 1, 1, 5, 6, 7, 8 };
byte[] find = { 1 };
int indexNow = 0;
int[] indexes = (from i in input
let index = indexNow++
where i == find[0]
select index).ToArray();
Array.Reverse(indexes);
您indexes
的结果将是4,3,2,1
,如您所愿。
现在,如果您要搜索具有多个值的find
:
byte[] find = { 1, 0, 5, 6 };
然后你可以遍历查询:
byte[] input = { 0, 1, 1, 1, 1, 5, 6, 7, 8 };
byte[] find = { 1, 0, 5, 6 };
List<int[]> indexesList = new List<int[]>();
foreach (byte findNow in find){
int indexNow = 0;
int[] indexes = (from i in input
let index = indexNow++
where i == find[0]
select index).ToArray();
Array.Reverse(indexes);
indexesList.Add(indexes);
}
然后,您的所有结果都会显示在indexesList
中,如下所示:
4, 3, 2, 1
0
5
6
答案 1 :(得分:1)
这对我有用:
byte[] input = { 0, 1, 1, 1, 5, 6, 1, 1, 1, 7, 8, 1, 1, 1 };
byte[] find = { 1, 1, 1 };
var query =
input
.Select((x, n) => new
{
n,
found = input.Skip(n).Take(find.Length).SequenceEqual(find)
})
.Where(x => x.found)
.Select(x => x.n)
.Reverse();
我得到{ 11, 6, 1 }
。
如果我从:
开始byte[] input = { 0, 1, 0, 0, 1, 1, 0, };
byte[] find = { 1, };
...然后我得到{ 5, 4, 1 }
。
这是一个功能:
public IEnumerable<int> SearchBytes(byte[] haystack, byte[] needle)
{
return
haystack
.Select((x, n) => new
{
n,
found = haystack.Skip(n).Take(needle.Length).SequenceEqual(needle)
})
.Where(x => x.found)
.Select(x => x.n)
.Reverse();
}