c# - 在 C# 中搜索字节数组中的最长模式

标签 c# arrays byte design-patterns match

我需要编写有效且快速的方法来搜索给定模式的字节数组。 我是这样写的,你觉得怎么样,如何改进?它有一个错误,它不能返回长度为 1 的匹配项。

public static bool SearchByteByByte(byte[] bytes, byte[] pattern)
    {
        bool found = false;
        int matchedBytes = 0;
        for (int i = 0; i < bytes.Length; i++)
        {
            if (pattern[0] == bytes[i] && bytes.Length - i >= pattern.Length)
            {
                for (int j = 1; j < pattern.Length; j++)
                {
                    if (bytes[i + j] == pattern[j])
                    {
                        matchedBytes++;
                        if (matchedBytes == pattern.Length - 1)
                        {
                            return true;
                        }
                        continue;
                    }
                    else
                    {
                        matchedBytes = 0;
                        break;
                    }
                }
            }
        }
        return found;
    }

有什么建议吗?

最佳答案

grep 中使用的 Boyer-Moore 算法非常高效,对于较长的模式大小会变得更加高效。我很确定您可以毫不费力地将它用于字节数组,并且它的 wikipedia page有一个 Java 实现,应该很容易移植到 C#。

更新:

这是在 C# 中针对字节数组的 Boyer-Moore 算法的简化版本的实现。它只使用 second jump table的完整算法。根据您所说的数组大小(haystack:2000000 字节,needle:10 字节),它比简单的逐字节算法快大约 5-8 倍。

    static int SimpleBoyerMooreSearch(byte[] haystack, byte[] needle)
    {
        int[] lookup = new int[256];
        for (int i = 0; i < lookup.Length; i++) { lookup[i] = needle.Length; }

        for (int i = 0; i < needle.Length; i++)
        {
            lookup[needle[i]] = needle.Length - i - 1;
        }

        int index = needle.Length - 1;
        var lastByte = needle.Last();
        while (index < haystack.Length)
        {
            var checkByte = haystack[index];
            if (haystack[index] == lastByte)
            {
                bool found = true;
                for (int j = needle.Length - 2; j >= 0; j--)
                {
                    if (haystack[index - needle.Length + j + 1] != needle[j])
                    {
                        found = false;
                        break;
                    }
                }

                if (found)
                    return index - needle.Length + 1;
                else
                    index++;
            }
            else
            {
                index += lookup[checkByte];
            }
        }
        return -1;
    }

关于c# - 在 C# 中搜索字节数组中的最长模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9889427/

相关文章:

Java:不同的byte[]在utf8中具有相同的字符串

c# - 如何将 IntPtr 转换回对象

c# - 需要帮助避免使用单例

不能在 C 中将 sscanf() 用于字符数组

javascript - PHP - JSON 字符串的 json_decode() 为空

javascript - XMLHTTPRequest 字节范围请求

c# - 如何使用 .NET 的 WebBrowser 或 mshtml.HTMLDocument 动态生成 HTML 代码?

c# - 游戏关卡意外地相互叠加

arrays - 算术平均的二维数组算法

c# - 无法转换为特定格式 C#