Boyer Moore Partial Pattern Search
using System;
using System.Collections.Generic;
public class BMPartialPatternSearch
{
public int MinimumSearchLength;
public BMPartialPatternSearch(int min = 5)
{
MinimumSearchLength = min;
}
public (byte[] partialPattern, int idx) SearchPartial(byte[] pattern, byte[] searchArray)
{
var bm = new BoyerMoore(pattern);
var len = pattern.Length;
var tree = new List<byte[]>();
if (len < MinimumSearchLength)
throw new Exception("Search Pattern less than minimum search length.");
var offset = 0;
var wl = MinimumSearchLength;
do
{
var tpat = new byte[wl];
Array.Copy(pattern, offset, tpat, 0, wl);
tree.Add(tpat);
bm.SetPattern(tpat);
var idx = bm.Search(searchArray);
if (idx != -1)
return (tpat, idx);
if (offset + wl >= len)
{
offset = 0;
wl++;
continue;
}
offset++;
} while (wl != len + 1);
return (pattern, -1);
}
public List<(byte[] partialPattern, int idx)> SearchPartialFirst(byte[] pattern, byte[] searchArray)
{
var bm = new BoyerMoore(pattern);
var len = pattern.Length;
var lst = new List<(byte[] partialPattern, int idx)>();
var tree = new List<byte[]>();
if (len < MinimumSearchLength)
throw new Exception("Search Pattern less than minimum search length.");
var offset = 0;
var wl = MinimumSearchLength;
do
{
var tpat = new byte[wl];
Array.Copy(pattern, offset, tpat, 0, wl);
tree.Add(tpat);
bm.SetPattern(tpat);
var idx = bm.Search(searchArray);
if (idx != -1)
lst.Add((tpat, idx));
if (offset + wl >= len)
{
offset = 0;
wl++;
continue;
}
offset++;
} while (wl != len + 1);
return new List<(byte[] partialPattern, int idx)> {(pattern, -1)};
}
public List<(byte[] partialPattern, int idx)> SearchPartialAll(byte[] pattern, byte[] searchArray)
{
var bm = new BoyerMoore(pattern);
var len = pattern.Length;
var lst = new List<(byte[] partialPattern, int idx)>();
var tree = new List<byte[]>();
if (len < MinimumSearchLength)
throw new Exception("Search Pattern less than minimum search length.");
var offset = 0;
var wl = MinimumSearchLength;
do
{
var tpat = new byte[wl];
Array.Copy(pattern, offset, tpat, 0, wl);
tree.Add(tpat);
bm.SetPattern(tpat);
var idxl = bm.SearchAll(searchArray);
if (idxl.Item1.Count > 0)
foreach (var idx in idxl.Item1)
lst.Add((tpat, idx));
if (offset + wl >= len)
{
offset = 0;
wl++;
continue;
}
offset++;
} while (wl != len + 1);
return lst;
}
public static Dictionary<string, int> SearchPartialSubSet(byte[] searchArray, int startLength, int endLength)
{
var pattern = (byte[]) searchArray.Clone();
var bm = new BoyerMoore(pattern);
var pLen = pattern.Length;
var lst = new Dictionary<string, int>();
var tree = new List<byte[]>();
if (pLen < endLength)
throw new Exception("Search Pattern less than minimum search length.");
var offset = 0;
var wl = startLength;
do
{
var tpat = new byte[wl];
Array.Copy(pattern, offset, tpat, 0, wl);
tree.Add(tpat);
bm.SetPattern(tpat);
var idxl = bm.SearchAll(searchArray);
if (idxl.Item1.Count > 1)
{
var sapat = tpat.ToHexString();
if (!lst.ContainsKey(sapat))
lst.Add(sapat, idxl.Item1.Count);
}
if (offset + wl >= pLen)
{
offset = 0;
wl++;
if (wl > endLength)
break;
continue;
}
offset++;
} while (wl != pLen + 1);
return lst;
}
public static Dictionary<string, int> SearchPartialSubSet(byte[] searchArray1, byte[] searchArray2, int startLength, int endLength)
{
var bm = new BoyerMoore(searchArray2);
var pLen = searchArray2.Length;
var lst = new Dictionary<string, int>();
var tree = new List<byte[]>();
if (pLen < endLength)
throw new Exception("Search Pattern less than minimum search length.");
var offset = 0;
var wl = startLength;
do
{
var tpat = new byte[wl];
Array.Copy(searchArray2, offset, tpat, 0, wl);
tree.Add(tpat);
bm.SetPattern(tpat);
var idxl = bm.SearchAll(searchArray1);
if (idxl.Item1.Count > 1)
{
var sapat = tpat.ToHexString();
if (!lst.ContainsKey(sapat))
lst.Add(sapat, idxl.Item1.Count);
}
if (offset + wl >= pLen)
{
offset = 0;
wl++;
if (wl > endLength)
break;
continue;
}
offset++;
} while (wl != pLen + 1);
return lst;
}
}