I have an algorithm that evaluates in input byte[] with a source byte[]. Several conditions can be encountered:Match foundNo match foundEnd of input arrayEnd of source array  Input wildcard (*) matches against any source byteAll of these conditions are dealt with in this algorithm. Having been my first pass at this algorithm, I know there are improvements that can be made. Not only am I looking for cleaner code and possibly refactoring to find re-usable bits, this needs to be as efficient as possible. Right now this will compare an 18 byte input array against an 1170 byte source array in 2ms.Here is the current implementation of the algorithm:private bool HasMatchBytes(byte[] bytes, out int length, ref int position) {    var hasMatch = false;    var isComplete = false;    var b = position;    var end = position;    //   - this loop depends on internal advancement of the counter [v]    for (var v = 0; v < bytes.Length; ) {        var isMatch = false;        //  - this loop depends on internal advancement of the counter [b]        while (b < mByteStream.Length &&               !isComplete) {            //  wildcard doesn't care the value            if (bytes[v] == '*') {                isMatch = true;            }            else {                isMatch = bytes[v] == mByteStream[b];            }            //  only advance positions if hasMatch is currently false            if (isMatch && !hasMatch) {                hasMatch = true;                position = b++;                ++v;            }            //  current position does not match and invalidates previous buffers            else if (!isMatch && hasMatch) {                hasMatch = false;                //  reset v (bytes array)                v = 0;                //  advance b (stream array)                ++b;            }            //  any other condition should advance b (stream array)            //      and v (bytes array)            else {                //  advance v (bytes array)                if (isMatch && hasMatch) {                    ++v;                }                //  we could have reached the end of v                if (v < bytes.Length) {                    if (hasMatch) {                        end = ++b;                    }                    else {                        ++b;                    }                }                //  if so, force completion                else {                    isComplete = true;                }            }        }        //  isMatch means the current byte indexes match        //  assumptions:        //      wherever the buffer position is, the results are        //          true to the current start position.        if (hasMatch && v < bytes.Length) {            ++v;            end = ++b;            if (b >= mByteStream.Length) {                hasMatch = false;            }        }        //  with match and at end of bytes length algorithm is complete        if (hasMatch &&            v >= bytes.Length) {            isComplete = true;            end = ++b;        }        //  if end of source reached then shut down algorithm        if (b >= mByteStream.Length) {            v = bytes.Length;            isComplete = true;            end = mByteStream.Length;        }    }    length = end - position;    return hasMatch;}...using .Net 4.5 if that helps.Edit per comment In all cases, the algorithm will return true if the source sequence contains a match against the full input array sequence. Each byte must match specifically in sequence except where a wildcard (*) is specified.This algorithm is intended to continue reading until end of the source array. If the end of the source array is reached before another full iterative match of the input array, the algorithm would return false. But the calling method uses the returned position plus the length of the input sequence to determine if there could possibly be another match in the source.  Here is the calling code:    public IEnumerable<IMetaToken> Matches(IMatchToken matchToken) {        var bytes = matchToken.GetValues();        var length = 0;        var position = 0;        while ((position + bytes.Length) < mByteStream.Length) {            if (HasMatchBytes(bytes, out length, ref position)) {                var start = position;                position += length;                var token = new MetaToken(start, length);                yield return token;            }            else {                position += length;            }        }    }FWIW:  This is part of a Regex-like class that handles expressions against byte arrays. First you have to create a format object and then have the ByteRegex class find Matches against the supplied source sequence.I've decided to take @svick's advice ...well, somewhat. I've already worked on renaming the indexes, etc.I have another class that manipulates a MemoryStream and I could use that to encapsulate this operation. At least the code would be in a class with the same order of operations.I am also going to refactor this huge method into 2 static iterator methods: IterateNeedle(...) and IterateHaystack(...). Names are likely to be changed to protect the innocent but you get the idea. I'll post some code once I have it reworked.  UPDATE Iterators to the rescueI don't know if I should post my refactors as an answer. Might be helpful for people to see implementation of the IEnumerator state machine.  I'll post explanation as an answer. There is a lot of code though and it is specialized so I'm hesitant because it might draw a lot of questions that are off topic.
Simplification of byte array comparison algorithm
c#;algorithm;.net;array
If I understand this correctly, your code doesn't work. This is because when some characters match and then you find a character that doesn't match, you can't continue checking with the current character, you need to go back to the second character of the current partial match.An example is mByteStream = new byte[] { 0, 0, 1 }, bytes = new byte[] { 0, 1 }. For this input, the correct result is true, but your code returns false.It looks like this method is part of a type that does other things. I think it would be cleaner if it was in a separate type, taking both arrays as parameters.When reading the code, it's very easy to confuse bytes and mByteStream, b and v. Those names don't mean anything. Much better names would be for example needle, haystack, needleIndex and haystackIndex. Having different variables names hasMatch and isMatch is also very confusing.A method that's this complicated would benefit greatly from detailed XML documentation. That way, callers of the method don't need to read its code to know what it does.