2011-09-06 7 views
6

que tienen una matriz de bytes:¿Cómo buscar en una matriz BYTE para un patrón?

BYTE Buffer[20000]; esta matriz contiene los siguientes datos:

00FFFFFFFFFFFF0010AC4C4053433442341401030A2F1E78EEEE95A3544C99260F5054A54B00714F8180B3000101010101010101010121399030621A274068B03600DA281100001C000000FF003457314D44304353423443530A000000FC0044454C4C2050323231300A2020000000FD00384B1E5310000A20202020202000FA

Mi pregunta es ¿cómo se puede buscar en esta matriz de un patrón como "000000FC"? Realmente no creo que sea importante, pero necesito el índice donde puedo encontrar mi patrón también. Podría alguien proporcionar un ejemplo para esto, porque yo realmente no entiendo esto :(

+0

Es exactamente lo mismo que buscar una subcadena en una cadena más grande. [Wikipedia] (http://en.wikipedia.org/wiki/String_searching_algorithm) tiene mucha información. – Joey

+1

Parece que [strstr()] (http://pubs.opengroup.org/onlinepubs/9699919799/functions/strstr.html) (en C, no sé nada de C++) hace lo que quiere. – pmg

+3

@pmg: 'strstr()' funciona en matrices terminadas en cero. No funcionará en estos, que contienen bytes de valor cero. –

Respuesta

23

Desde estás en C++, hazlo de la manera C++:

char a[] = { 0, 0, 0, 0xFC }; 
char Buffer[20000] = ... 

std::string needle(a, a + 4); 
std::string haystack(Buffer, Buffer + 20000); // or "+ sizeof Buffer" 

std::size_t n = haystack.find(needle); 

if (n == std::string::npos) 
{ 
    // not found 
} 
else 
{ 
    // position is n 
} 

También puede utilizar un algoritmo para buscar la matriz directamente:

#include <algorithm> 
#include <iterator> 

auto it = std::search(
    std::begin(Buffer), std::end(Buffer), 
    std::begin(a), std::end(a)); 

if (it == std::end(Buffer)) 
{ 
    // not found 
} 
else 
{ 
    // subrange found at std::distance(std::begin(Buffer), it) 
} 

O, en C++ 17, se puede utilizar una vista cadena:

std::string_view sv(std::begin(Buffer), std::end(Buffer)); 

if (std::size_t n = sv.find(needle); n != sv.npos) 
{ 
    // found at position n 
} 
else 
{ 
    // not found 
} 
+0

¡Muchas gracias! – kampi

+0

No hay problema. También puede crear la aguja en una línea: 'std :: string needle (" \ 0x00 \ 0x00 \ 0x00 \ 0xFC ", 4);'. Le ahorra un temporal :-) –

+0

supone que la aguja está alineada con la palabra. ** EDIT: ** acaba de notar que dice una matriz "BYTE" y no una matriz "BIT". – phoxis

6

¿Quieres algo así como memmem (que el código está licenciado con la GPL).

Sin embargo, no debería ser difícil de rodar el suyo propio. al igual que en la implementación memmem 's, necesita un bucle que utiliza memchr para encontrar el primer carácter de su aguja en el pajar, y memcmp para probar cada golpe y ver si todo su aguja está allí.

+0

Esa es la peor implementación posible de 'memmem' ... –

+0

@R ..: Es cierto que no busqué a otros, y solo me vinculé a él como ejemplo. En los zapatos del OP tomaría mi propio consejo y lo haría, ya que es una cuestión realmente simple. – Jon

+0

Rodar uno mismo no es una mala idea, pero O (N²) es bastante malo, especialmente cuando O (N) con el mejor caso que se aproxima a N/M es posible ... –

1

probar esto, solo necesita it:

// Returns a pointer to the first byte of needle inside haystack, 
static uint8_t* bytes_find(uint8_t* haystack, size_t haystackLen, uint8_t* needle, size_t needleLen) { 
    if (needleLen > haystackLen) { 
     return false; 
    } 
    uint8_t* match = memchr(haystack, needle[0], haystackLen); 
    if (match != NULL) { 
     size_t remaining = haystackLen - ((uint8_t*)match - haystack); 
     if (needleLen <= remaining) { 
      if (memcmp(match, needle, needleLen) == 0) { 
       return match; 
      } 
     } 
    } 
    return NULL; 
} 
Cuestiones relacionadas