字节模式发现(干草堆中的针) - 通配符/面具?

时间:2015-02-04 19:40:27

标签: c# arrays byte wildcard mask

这是我第一次使用StackOverflow,很抱歉,如果我模糊:P

我有这段代码,它在字节数组中搜索模式并返回它的位置。

public int FindPattern(byte[] Body, byte[] Pattern, int start = 0)
    {
        int foundIndex = -1;
        bool match = false;

        if (Body.Length > 0 && Pattern.Length > 0 && start <= Body.Length - Pattern.Length && Pattern.Length <= Body.Length)
            for (int index = start; index <= Body.Length - Pattern.Length; index += 4)
                if (Body[index] == Pattern[0])
                {
                    match = true;
                    for (int index2 = 1; index2 <= Pattern.Length - 1; index2++)
                    {
                        if (Body[index + index2] != Pattern[index2])
                        {
                            match = false;
                            break;
                        }

                    }

                    if (match)
                    {
                        foundIndex = index;
                        break;
                    }
                }

        return foundIndex;
    }

问题是我不知道如何包括Byte Masking / Wildcards。

例如,如果我想找到以下字节模式:

0x5A, 0xC7, 0xAE, 0xB7, 0x2F

如何实现通配符搜索,这样如果我不知道字节数组中的某些字节或它们发生了变化,例如,我将如何找到如下模式:

0x5A, 0x??, 0xAE, 0xB7, 0x??

?? =表示我不时知道哪些更改的字节。

有没有人有解决方案? - 我环顾四周但找不到多少信息

非常感谢提前!, 詹姆斯

1 个答案:

答案 0 :(得分:1)

修改代码以支持通配符非常简单。提高搜索大量数据的效率可能需要一个更复杂的算法,比如带有通配符的Boyer-Moore(抱歉,我不会有代码存在)。

这是做前者的一种方式(脱离我的头脑):

public int FindPattern(byte[] Body, byte[] Pattern, bool[] Wild, int start = 0)
    {
        int foundIndex = -1;
        bool match = false;

        if (Body.Length > 0 
            && Pattern.Length > 0 
            && start <= Body.Length - Pattern.Length && Pattern.Length <= Body.Length)
            for (int index = start; index <= Body.Length - Pattern.Length; index += 4)

                if (Wild[0] || (Body[index] == Pattern[0]))
                {
                    match = true;
                    for (int index2 = 1; index2 <= Pattern.Length - 1; index2++)
                    {
                        if (!Wild[index2] &&
                          (Body[index + index2] != Pattern[index2]))
                        {
                            match = false;
                            break;
                        }

                    }

                    if (match)
                    {
                        foundIndex = index;
                        break;
                    }
                }

        return foundIndex;
    }

这里的期望是你传入搜索模式的全长,然后传递一个相同长度的通配符标志数组,所以你的例子

0x5A, 0x??, 0xAE, 0xB7, 0x??

将作为

传递
0x5A, 0x00, 0xAE, 0xB7, 0x00, and then
false, true, false, false, true