Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find indexOf a byte array within another byte array

Given a byte array, how can I find within it, the position of a (smaller) byte array?

This documentation looked promising, using ArrayUtils, but if I'm correct it would only let me find an individual byte within the array to be searched.

(I can't see it mattering, but just in case: sometimes the search byte array will be regular ASCII characters, other times it will be control characters or extended ASCII characters. So using String operations would not always be appropriate)

The large array could be between 10 and about 10000 bytes, and the smaller array around 10. In some cases I will have several smaller arrays that I want found within the larger array in a single search. And I will at times want to find the last index of an instance rather than the first.

like image 701
CL22 Avatar asked Jan 24 '14 19:01

CL22


People also ask

How do I combine byte arrays?

To concatenate multiple byte arrays, you can use the Bytes. concat() method, which can take any number of arrays.

How do you know if two byte arrays are equal?

equals(byte[] a, byte[] a2) method returns true if the two specified arrays of bytes are equal to one another. Two arrays are equal if they contain the same elements in the same order. Two array references are considered equal if both are null.

Can you serialize byte array?

We can use a ByteArrayOutputStream and ObjectOutputStream object to serializable an object to a byte array. Note that our User class must implement the Serializable interface.

How do you find byte array?

We can also get the byte array using the below code. byte[] byteArr = str. getBytes("UTF-8"); However if we provide Charset name, then we will have to either catch UnsupportedEncodingException exception or throw it.


2 Answers

The simpelst way would be to compare each element:

public int indexOf(byte[] outerArray, byte[] smallerArray) {     for(int i = 0; i < outerArray.length - smallerArray.length+1; ++i) {         boolean found = true;         for(int j = 0; j < smallerArray.length; ++j) {            if (outerArray[i+j] != smallerArray[j]) {                found = false;                break;            }         }         if (found) return i;      }    return -1;   }   

Some tests:

@Test public void testIndexOf() {   byte[] outer = {1, 2, 3, 4};   assertEquals(0, indexOf(outer, new byte[]{1, 2}));   assertEquals(1, indexOf(outer, new byte[]{2, 3}));   assertEquals(2, indexOf(outer, new byte[]{3, 4}));   assertEquals(-1, indexOf(outer, new byte[]{4, 4}));   assertEquals(-1, indexOf(outer, new byte[]{4, 5}));   assertEquals(-1, indexOf(outer, new byte[]{4, 5, 6, 7, 8})); } 

As you updated your question: Java Strings are UTF-16 Strings, they do not care about the extended ASCII set, so you could use string.indexOf()

like image 165
morpheus05 Avatar answered Sep 25 '22 18:09

morpheus05


Google's Guava provides a Bytes.indexOf(byte[] array, byte[] target).

like image 25
ant-depalma Avatar answered Sep 22 '22 18:09

ant-depalma