C# 如何在反向字节数组中找到字节数组?

C# How to find a byte array inside a byte array going reverse?

我正在尝试在另一个字节数组 byte[] 中找到一个字节数组 byte[] 进行反向操作。

问题:如何从头到尾在另一个字节数组中搜索一个字节数组?

这个link是我正在制作的代码的参考

编辑: 我需要将此代码转换为在另一个字节数组中搜索字节数组。

        indexPos = SearchBytes(input, find, indexPos);

        Console.WriteLine("Found at " + indexPos);

        indexPos += find.Length;

UPDATED: 当我点击按钮时,索引需要搜索如下: 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;
    }

您可以使用 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

这对我有用:

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();
}