Если шаблон, который вы ищете, является фиксированным, вы можете построить серию массивов, которые являются сдвигами в масках, чтобы сделать сравнения. Для сравнения используйте функцию xor и, если возвращается 0, она совпадает. Любое другое значение не совпадает. Это позволит проверять байты в строке, если в массиве осталось не менее 2 байтов. Если осталось 2 байта, вы не сможете увеличить целые восемь битов. Пример для 17 бит приведен ниже, но это та же идея. (Я ищу все, с которыми было легко работать, сдвигая биты для демонстрации)
/* Data is passed in, and offset is the number of bits offset from the first
bit where the mask is located
returns true if match was found.
*/
bool checkData(char* data, int* offset)
{
/* Mask to mask off the first bits not being used or examined*/
static char firstMask[8] = { 0xFF, 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01 };
/* Mask to mask off the end bits not used or examined*/
static char endMask[8] = { 0x80, 0xC0, 0xE0, 0x0F, 0xF8, 0xFC, 0xFE, 0xFF };
/* Pattern which is being search, with each row being the about shifted and
columns contain the pattern to be compared. for example index 0 is a
shift of 0 bits in the pattern and 7 is a shift of seven bits
NOTE: Bits not being used are set to zero.
*/
static char pattern[8][3] = { { 0xFF, 0xFF, 0x80 }, /* Original pattern */
{ 0x8F, 0xFF, 0xC0 }, /* Shifted by one */
{ 0x3F, 0xFF, 0xE0 }, /* Shifted by two */
{ 0x1F, 0xFF, 0xF0 },
{ 0x0F, 0xFF, 0xF8 },
{ 0x07, 0xFF, 0xFC },
{ 0x03, 0xFF, 0xFE },
{ 0x01, 0xFF, 0xFF }}; /* shifted by seven */
/* outer loop control variable */
int lcv;
/* inter loop control variable */
int lcv2;
/* value to to contain the value results */
char value;
/* if there is no match, pass back a negative number to indicate no match */
*offset = -1;
/* Loop through the shifted patterns looking for a match */
for ( lcv = 0; lcv < 8 ; lcv++ )
{
/* check the first part of the pattern.
mask of part that is not to be check and xor it with the
first part of the pattern */
value = (firstMask[lcv] & *data) ^ pattern[lcv][0];
/* if value is not zero, no match, so goto the next */
if ( 0 != value )
{
continue;
}
/* loop through the middle of the pattern make sure it matches
if it does not, break the loop
NOTE: Adjust the condition to match 1 less then the number
of 8 bit items you are comparing
*/
for ( lcv2 = 1; lcv2 < 2; lcv2++)
{
if ( 0 != (*(data+lcv2)^pattern[lcv][lcv2]))
{
break;
}
}
/* if the end of the loop was not reached, pattern
does not match, to continue to the next one
NOTE: See note above about the condition
*/
if ( 2 != lcv2)
{
continue;
}
/* Check the end of the pattern to see if there is a match after masking
off the bits which are not being checked.
*/
value = (*(data + lcv2) & endMask[lcv]) ^ pattern[lcv][lcv2];
/* if value is not zero, no match so continue */
if ( 0 != value )
{
continue;
}
}
/* If the end of the loop was not reached, set the offset as it
is the number of bits the pattern is offset in the byte and
return true
*/
if ( lcv < 8 )
{
*offset = lcv ;
return true;
}
/* No match was found */
return false;
}
Для этого пользователю необходимо указать указатель на данные и вызвать его для следующего байта. Пользователь должен убедиться, что он не будет проходить через конец данных в сопоставлении с образцом.
Если в шаблоне нет совпадения на ранней стадии, он не будет проверять оставшиеся биты, что должно помочь в поиске.
Эта реализация должна быть достаточно переносимой, но для 37-битной обработки потребуется некоторая переделка.