using System; using System.Diagnostics; namespace ConsoleApplication1 { internal class Program { /// Looks for the next occurrence of a sequence in a byte array /// Array that will be scanned /// Index in the array at which scanning will begin /// Sequence the array will be scanned for /// /// The index of the next occurrence of the sequence of -1 if not found /// private static int findSequence(byte[] array, int start, byte[] sequence) { int end = array.Length - sequence.Length; // past here no match is possible byte firstByte = sequence[0]; // cached to tell compiler there's no aliasing while(start <= end) { // scan for first byte only. compiler-friendly. if(array[start] == firstByte) { // scan for rest of sequence for (int offset = 1;; ++offset) { if(offset == sequence.Length) { // full sequence matched? return start; } else if(array[start + offset] != sequence[offset]) { break; } } } ++start; } // end of array reached without match return -1; } private static void checkSingleByteSequence() { byte[] sequence = new byte[] { 123 }; Debug.Assert(findSequence(new byte[] { 123 }, 0, sequence) == 0); Debug.Assert(findSequence(new byte[] { 100 }, 0, sequence) == -1); Debug.Assert(findSequence(new byte[] { 123, 124, 125 }, 0, sequence) == 0); Debug.Assert(findSequence(new byte[] { 122, 123, 124 }, 0, sequence) == 1); Debug.Assert(findSequence(new byte[] { 121, 122, 123 }, 0, sequence) == 2); Debug.Assert(findSequence(new byte[] { 123, 124, 125, 126 }, 1, sequence) == -1); Debug.Assert(findSequence(new byte[] { 122, 123, 124, 125 }, 2, sequence) == -1); Debug.Assert(findSequence(new byte[] { 123, 124, 123, 124 }, 1, sequence) == 2); Debug.Assert(findSequence(new byte[] { 120, 121, 122, 123 }, 3, sequence) == 3); Debug.Assert(findSequence(new byte[] { 121, 122, 123, 124 }, 3, sequence) == -1); } private static void checkThreeByteSequence() { byte[] sequence = new byte[] { 150, 150, 160 }; Debug.Assert(findSequence(new byte[] { 100 }, 0, sequence) == -1); Debug.Assert(findSequence(new byte[] { 100, 200 }, 0, sequence) == -1); Debug.Assert(findSequence(new byte[] { 100, 110 }, 1, sequence) == -1); Debug.Assert(findSequence(new byte[] { 100, 110, 120 }, 0, sequence) == -1); Debug.Assert(findSequence(new byte[] { 100, 110, 120, 130 }, 3, sequence) == -1); Debug.Assert(findSequence(new byte[] { 150 }, 0, sequence) == -1); Debug.Assert(findSequence(new byte[] { 100, 150 }, 0, sequence) == -1); Debug.Assert(findSequence(new byte[] { 150, 150 }, 1, sequence) == -1); Debug.Assert(findSequence(new byte[] { 100, 150, 150, 150 }, 0, sequence) == -1); Debug.Assert(findSequence(new byte[] { 150, 150, 120, 150 }, 3, sequence) == -1); Debug.Assert(findSequence(new byte[] { 150, 150, 160, 170 }, 0, sequence) == 0); Debug.Assert(findSequence(new byte[] { 150, 150, 160, 170 }, 1, sequence) == -1); Debug.Assert(findSequence(new byte[] { 140, 150, 150, 160 }, 0, sequence) == 1); Debug.Assert(findSequence(new byte[] { 140, 150, 150, 160 }, 1, sequence) == 1); Debug.Assert(findSequence(new byte[] { 140, 150, 150, 160 }, 2, sequence) == -1); } public static void Main(string[] args) { checkSingleByteSequence(); checkThreeByteSequence(); } } }