2

I'm trying to find a byte array byte[] inside another byte array byte[] going reverse.

Question: How can I search a byte array inside another byte array from end to start?

This link is a reference of the code I'm making c# How to Continuously find a byte array inside a byte array?

EDIT: I need this code converted to searching for a byte arry within another byte array going reverse.

 indexPos = SearchBytes(input, find, indexPos); Console.WriteLine("Found at " + indexPos); indexPos += find.Length; 

UPDATED: When I click the button, the index needs to search as follows: 11, 6 1

This code below is what I need to have searching from end to start:

byte[] input = { 0, 1, 1, 1, 5, 6, 1, 1, 1, 7, 8, 1, 1, 1 }; byte[] find = { 1, 1, 1 }; int indexPos = 0; private void button1_Click(object sender, EventArgs e) { indexPos = SearchBytes(input, find, indexPos); Console.WriteLine("Found at " + indexPos); indexPos += find.Length; } public int SearchBytes(byte[] haystack, byte[] needle, int start_index) { int len = needle.Length; int limit = haystack.Length - len; for (int i = start_index; i <= limit; i++) { int k = 0; for (; k < len; k++) { if (needle[k] != haystack[i + k]) break; } if (k == len) return i; } return -1; } 
5
  • Just to clarify: for example, if you have haystack 0, 1, 1, 1, 1, 5, 6, 7, 8 and your needle is 1 would you return 1 or 4 as index position? And if your needle is 1 5, would you return index 4, 5, or would you return -1 (not found)? And lastly, if your needle is 5 1, would you return 4, 5, or would you return -1 (not found)? Commented Jan 22, 2016 at 6:47
  • @Ian I need it to return to 4 then 3 and so on in that order. Commented Jan 22, 2016 at 7:41
  • I see, and what happened if you have haystack 1 2 1 2 1 2? if your needle is 1 2, would you return 4 then 2 then 0 (note that I bold it)? or, you would read from backwards 2 1 2 1 2 1 and thus the last one will lack of 2 and you will only return 4 then 2? Commented Jan 22, 2016 at 7:44
  • @Ian haystack 0 1 0 0 1 1 0 needle 1 I need it to find the numbers in this order: 5, 4, 1. Then the next index will be -1 to restart. I'm simply trying to make the code reverse its searching.. I'll appreciate an answer. Thanks. Commented Jan 22, 2016 at 8:02
  • I got it pretty much and I was about to help, but I just wondered why you use byte[] in your needle instead of byte if you only can have 1 byte. That's why I keep giving examples of multiple bytes as needle. So, will your needle only be 1 byte? can it be multiple bytes? Commented Jan 22, 2016 at 8:04

2 Answers 2

2

You can use LINQ query as well as Array.Reverse to help you.


Edit:

To find the pattern of multiple bytes, you need to update the LINQ query like this

byte[] input = { 0, 1, 1, 1, 5, 6, 1, 1, 1, 7, 8, 1, 1, 1 }; byte[] find = { 1, 1, 1 }; int indexNow = 0; int findLength = find.Length; int[] indexes = (from i in input let index = indexNow++ where index <= input.Length - findLength //cannot exceeds this on the search let compared = input.Skip(index).Take(findLength) where Enumerable.SequenceEqual(find, compared) select index).Reverse().ToArray(); 

And the result in your indexes will be 11,6,1 as you wanted.

To use a function, simply put all the queries and inputs used above to a function returning indexes.

public int[] SearchBytes(byte[] input, byte[] find){ int indexNow = 0; return (from i in input let index = indexNow++ where index <= input.Length - find.Length//cannot exceeds this on the search let compared = input.Skip(index).Take(find.Length) where Enumerable.SequenceEqual(find, compared) select index).Reverse().ToArray(); } 

Original:

Assuming you only define one byte needle as discussed in the comments, you could do it like this:

byte[] input = { 0, 1, 1, 1, 1, 5, 6, 7, 8 }; byte[] find = { 1 }; int indexNow = 0; int[] indexes = (from i in input let index = indexNow++ where i == find[0] select index).ToArray(); Array.Reverse(indexes); 

And the result in your indexes will be 4,3,2,1 as you wanted.

Now if you want to search for find with multiple values:

byte[] find = { 1, 0, 5, 6 }; 

Then you could loop over the query:

byte[] input = { 0, 1, 1, 1, 1, 5, 6, 7, 8 }; byte[] find = { 1, 0, 5, 6 }; List<int[]> indexesList = new List<int[]>(); foreach (byte findNow in find){ int indexNow = 0; int[] indexes = (from i in input let index = indexNow++ where i == find[0] select index).ToArray(); Array.Reverse(indexes); indexesList.Add(indexes); } 

Then all your results will be in the indexesList as follow:

4, 3, 2, 1 0 5 6 
Sign up to request clarification or add additional context in comments.

2 Comments

The code that you made is working, but I need it to search a lot faster. The original code from this question is fast enough for what I'm doing, but can you convert it to go reverse and search as fast as the original code i posted in this question?
@JohnSmith I think that belongs to another question already... :/ probably there are some who can help you make faster algorithm in the code review. But there might be some who can do it in SO as well. Try to post it as new (separate) question with your updated code.
1

This works for me:

byte[] input = { 0, 1, 1, 1, 5, 6, 1, 1, 1, 7, 8, 1, 1, 1 }; byte[] find = { 1, 1, 1 }; var query = input .Select((x, n) => new { n, found = input.Skip(n).Take(find.Length).SequenceEqual(find) }) .Where(x => x.found) .Select(x => x.n) .Reverse(); 

I get { 11, 6, 1 }.

If I start with:

byte[] input = { 0, 1, 0, 0, 1, 1, 0, }; byte[] find = { 1, }; 

...then I get { 5, 4, 1 }.


Here it is as a function:

public IEnumerable<int> SearchBytes(byte[] haystack, byte[] needle) { return haystack .Select((x, n) => new { n, found = haystack.Skip(n).Take(needle.Length).SequenceEqual(needle) }) .Where(x => x.found) .Select(x => x.n) .Reverse(); } 

13 Comments

How would I use your answer to call it?
Somewhat yes, I still need to know how to use it. Example: indexPos = SearchBytes(input, find); indexPos += find.Length;
It produces an IEnumerable<int> which you can consume in a foreach or turn it to a list with .ToList(). How do you need to use it?
I need it to give me an int value so I can get my search index for a byte array. Can you make that function?
In your question you asked for it to return 11, 6, 1. Do you want it to return the .First() value, or the .Last() value or the .ElementAt(n) value?
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.