Skip to content

Instantly share code, notes, and snippets.

@cameronism
Created May 27, 2014 14:27
Show Gist options
  • Select an option

  • Save cameronism/abfbb23f7993b4cd6956 to your computer and use it in GitHub Desktop.

Select an option

Save cameronism/abfbb23f7993b4cd6956 to your computer and use it in GitHub Desktop.
Needle in a haystack
// find the needle that exactly matches the specified portion of haystack
// will return -1 for count of 0
public static int NeedleIndex(byte[] haystack, int offset, int count, byte[][] needles)
{
Debug.Assert(needles.Length <= 8, "Can only search for up to 8 needles at once");
ulong mask = 0;
for (int i = 0; i < needles.Length; i++)
{
if (needles[i] != null && needles[i].Length == count)
{
mask = mask | ((ulong)1 << i);
}
}
// no candidates
if (mask == 0 || count == 0) return -1;
int match = -1;
int needleOffset = 0;
do
{
match = -1;
for (int i = 0; i < needles.Length; i++)
{
ulong bit = (ulong)1 << i;
if ((mask & bit) == 0) continue;
var needle = needles[i];
// check current byte
if (haystack[offset] != needle[needleOffset])
{
// not a match
mask = mask & ~bit;
// no candidates left
if (mask == 0) return -1;
}
else
{
match = i;
}
}
needleOffset++;
offset++;
} while(needleOffset < count);
return match;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment