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

时间:2016-01-22 06:38:48

标签: c# arrays search byte reverse

我正在尝试在另一个字节数组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;
    }

2 个答案:

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