I am trying to get this working in C Calculation of CRC in C seems easy but my CRC/BCH routine is not generating the same answer as in the link for the first codeword, even when I tried calculating manually and even that is not matching with what is given in the link.
My manual calculation was as
11101101001 101010011010000010100
111011010010000000000
010001001000000010100
11101101001
01100100001000010100
11101101001
0010010101100010100
11101101001
01111000101010100
11101101001
0001100001110100
11101101001
0010111010000
11101101001
01010111001 ---- remainder (should match with BCH(31,21) value in the link)
I am not sure where I am wrong. Here's my code
int calc_bch_and_parity( int cw_e )
{
int bit=0;
int local_cw = 0;
int parity = 0;
local_cw = cw_e;
for( bit=1; bit<=21; bit++, cw_e <<= 1 )
if (cw_e & 0x80000000)
cw_e ^= 0xED200000;
local_cw |= (cw_e >> 21);
cw_e =local_cw;
for( bit=1; bit<=32; bit++, cw_e <<= 1 )
if (cw_e & 0x80000000)
parity++;
return (parity%2) ? local_cw+1 : local_cw;
}
******************************edited code to get more visibility of the process **************
int bit=0;
int local_cw = 0;
int parity = 0;
// int try;
int answer;
// int genpoly = 0x1DA400;
local_cw=cw; /* bch */
for(bit=1; bit<=21; bit++, cw <<= 1)
{
if (cw & 0x80000000)
{
cw ^= 0xED200000;
printf ("mod2 remainder is %x\n", cw);
}
}
printf ("original data is %x\n", local_cw);
local_cw |= (cw >> 21);
printf ("21 bit right shifted remainder is %x\n",cw>>21);
cw =local_cw; /* parity */
for(bit=1; bit<=32; bit++, cw<<=1)
if (cw & 0x80000000) parity++;
{
if(parity%2)
{
printf("codeword is %x \n",local_cw+1 );
answer = local_cw+1;
}
else
{
printf("codeword is %x \n",local_cw );
answer =local_cw;
}
}
return answer;
The expected reminder is 1001111100
Another example of BCH .
One another thing I have tried is this http://www.codeproject.com/Articles/13189/POCSAG-Encoder , sorry I have to rely on external link as I can not post the image yet, in this link in the image you will see that there is a pre-encoded message visible in hex and the actual message is word "Salam, I managed to successfully transmit the message to a pager using this pre-encoded message (fed it to a transmitter as array of hex integers), But even this message, ie. the word "Salam" is not visible (at least the first or last or any 20 consecutive bits) in the encoded message. I converted the whole hex message in binary and the word "Salam" in binary and tried to find first or last 20 bits of the word "Salam" in the encoded message. Now that is very odd for a CRC (which basically BCH is), CRCs don't suppose to encode/twist the actual message it should just append it with remainder and parity (in case of BCH) . So the actual message should be visible as is, first or last 20 bits, I even tried changing endianess but no joy. Here are the details of my effort with this new example
Salam : 01010011 01100001 01101100 01100001 01101101
gx: 10010110111
Salam_reversed_by_byte: 11001010 10000110 00110110 10000110 10110110
Salam_ rev : 10110110 10000110 00110110 10000110 11001010
1234567 : 00110001001100100011001100110100001101010011011000110111
1234567_reverse :11101100011011001010110000101100110011000100110010001100
first 20 bits of Salam : 01010011011000010110 First20_reverse of Salam : 01101000011011001010
Hex CW : 0x4B5A1A25,0xE5866E6E,0x7CD215D8,0xE1DB221B,0x84081630
0x4B5A1A25 : 01001011010110100001101000100101
0xE5866E6E : 11100101100001100110111001101110
0xE1DB221B : 11100001110110110010001000011011
0x84081630 : 10000100000010000001011000110000
Works for me, all I did is pad the dividend out to 32bits
10101001101000001010000000000000
11101101001
01000100100000001010000000000000
11101101001
00110010000100001010000000000000
11101101001
00001001010110001010000000000000
11101101001
00000111100010101010000000000000
11101101001
00000000111000111010000000000000
11101101001
00000000000011101000000000000000
11101101001
00000000000000000101001000000000
11101101001
00000000000000000010010010010000
11101101001
00000000000000000001111111011000
11101101001
00000000000000000000001001111100
Here's the code that does the calculation "by hand"
#include <stdio.h>
#include <string.h>
char blank[] = " ";
char dividend[] = "10101001101000001010000000000000";
char divisor[] = "11101101001";
int main( void )
{
int i, j;
int N = strlen( dividend );
int M = strlen( divisor );
printf( "%d %d\n", N, M );
for ( i = 0; i < N - M; i++ )
{
if ( dividend[i] == '1' )
{
printf( "%s\n", dividend );
printf( "%s%s\n", &blank[N-i], divisor );
for ( j = 0; j < M; j++ )
{
if ( dividend[i+j] == divisor[j] )
dividend[i+j] = '0';
else
dividend[i+j] = '1';
}
}
}
printf( "%s\n", dividend );
}
And here's the same thing twiddling bits
#include <stdio.h>
#include <stdint.h>
int main( void )
{
uint32_t dividend = 0x153414;
uint32_t generator = 0x769;
uint32_t mask;
dividend <<= 11; // pad the dividend with 11 zeros
generator <<= 21; // left justify the generator
mask = 1 << 31; // start the mask at the MSB
for ( int i = 0; i < 21; i++ )
{
if ( dividend & mask ) // if the dividend has 1 at the current mask position
dividend ^= generator; // "subtract" the generator
generator >>= 1;
mask >>= 1; // move to the next bit
}
printf( "%08x\n", dividend ); // whatever's left is the remainder
}