Decoding it on the fly would be faster I think.
But, I am able to store the data first then parse through it.
My newsserver is having problems, so I've resorted to posting from
Google Groups.
If you can post-process it, I'd first decode the bit pairs, then shift
the pattern across the resulting decoded bits. The following code
should give you gist of it. The code is not portable, assumes
little-endian by ordering, could be optimized, etc.
Do notice that of the 4E 4E A1 that you saw, I don't find the A1 by
hand and neither does the program. However 4E 4E 14 is present.
-Dan Henry
#include <stdio.h>
#include <stdlib.h>
/* int find_bit_pattern(buffer, length, pattern, width)
*
* The function searches 'length' bits of 'buffer' bit-by-bit for the
* 'width'-bit 'pattern' ('width' must be <=24) and returns the bit
position
* where the pattern was found or -1 if not found.
*
* NOTE: This function assumes little-endian byte ordering.
*/
int find_bit_pattern(unsigned char *buffer,
unsigned length,
unsigned long pattern,
unsigned width)
{
union _32_BITS {
unsigned long ul;
unsigned char b[4];
};
union _32_BITS pat; /* Shifting search pattern */
union _32_BITS msk; /* Shifting match mask */
union _32_BITS xor; /* Pattern match result */
int pos = 0; /* Search's bit position */
unsigned long mask = 0;
unsigned i;
/* Left-justify pattern and pattern mask.
*/
for (i = 32 - width; i != 0; i--) {
pattern <<= 1;
mask = (mask << 1) | 1;
}
mask = ~mask;
msk.ul = mask;
pat.ul = pattern;
length -= width;
while (length--) {
xor.b[0] = (buffer[3] ^ pat.b[0]) & msk.b[0];
xor.b[1] = (buffer[2] ^ pat.b[1]) & msk.b[1];
xor.b[2] = (buffer[1] ^ pat.b[2]) & msk.b[2];
xor.b[3] = (buffer[0] ^ pat.b[3]) & msk.b[3];
if (xor.ul == 0) {
return pos;
} else {
/* Shift the pattern and mask 1 bit. Every 8 bits,
'advance' the
* pattern, mask, and buffer pointer to the next byte.
*/
msk.ul >>= 1;
if (msk.b[3] == 0) { /* 8 bits shifted? */
pat.ul = pattern;
msk.ul = mask;
buffer++;
} else {
pat.ul >>= 1;
}
}
pos++;
}
return -1;
}
int decode_pairs(unsigned char *pairs, size_t pairs_len, unsigned char
*decoded)
{
unsigned char pairs_bit = 0x80;
unsigned char decode_bit = 0x80;
*decoded = 0;
while (pairs_len != 0) {
if (*pairs & (pairs_bit >> 1)) {
if (*pairs & (pairs_bit >> 0)) {
return -1;
} else {
*decoded |= decode_bit;
}
}
if ((pairs_bit >>= 2) == 0) { /* Advance pairs by two bits */
pairs_bit = 0x80;
pairs_len--;
pairs++;
}
if ((decode_bit >>= 1) == 0) { /* Advance decode by one bit */
decode_bit = 0x80;
printf("%02X", (unsigned)*decoded);
*++decoded = 0;
}
}
if (decode_bit != 0x80) {
printf("%02X", (unsigned)*decoded);
}
putchar('\n');
return 0;
}
/* 01001010 01001001 01010010 01001001 01010010 00100100 01001010 RAW
*
* 01001010010010010101001001001001010100100010010001001010 RAW
* 1 0 0 0 1 0 0 1 1 1 0 0 1 0 0 1 1 1 0 0 0 0 1 0 1 0 0 0
DECODED
*
* NOTE: The Ch C interpreter's (
www.softintegration.com) sizeof
operator
* seems to not be quite right and needs parens.
*/
unsigned char raw_serial[] = {0x4A, 0x49, 0x52, 0x49, 0x52, 0x24,
0x4A};
unsigned char decoded_serial[((sizeof raw_serial)/2)+1];
int main(void)
{
int i;
if (decode_pairs(raw_serial, (sizeof raw_serial), decoded_serial)
!= 0) {
printf("Illegal bit pair in serial data string.\n");
exit(EXIT_FAILURE);
}
i = find_bit_pattern(decoded_serial, (sizeof decoded_serial)*8,
0x004E4E14, 24);
if (i < 0) {
printf("Pattern not found.\n");
} else {
printf("Pattern found at decoded bit position %d.\n", i);
}
exit(EXIT_SUCCESS);
}