Search code examples
c++boostcrcbitset

Checking CRC using boost library does not give satisfactory result


I am using the boost crc library to calculate a 32-bit crc of an 112-bit (80-bit data + 32-bit crc) bitset. For testing, I reset all 80 data bits to 0. The calculation of the crc seems to work fine, but when I append the calculated crc to the data and calculate the crc again, I get a value > 0. But I expected a crc value of exactly 0. Here is the code:

    // creating 112-bit bitset and reset all values to 0
    bitset<112> b_data;
    b_data.reset();

    // create string containing data and blank crc
    string crc_string = b_data.to_string<char,string::traits_type,string::allocator_type>();

    // calculating crc using boost library
    boost::crc_32_type crc32;
    crc32 = for_each(crc_string.begin(), crc_string.end(), crc32);
    bitset<32> b_crc(crc32());

    // writing calculated crc to the last 32-bit of the 112-bit bitset.
    for(int i = 0; i!= b_crc.size(); i++){
        b_data[i+80] = b_crc[i];
    }

    // create string containing data and calculated crc
    string crc_string_check = b_data.to_string<char,string::traits_type,string::allocator_type>();

    // calculate crc again to check if the data is correct
    boost::crc_32_type crc32_check;
    crc32_check = std::for_each(crc_string_check.begin(), crc_string_check.end(), crc32_check);

    // output the result
    cout << crc32() << endl;
    cout << crc32_check() << endl;

The output is:

    1326744236
    559431208

The output I have expected is:

    1326744236
    0

So something goes wrong, but what? Any ideas ?

Thanks in advance.


Solution

  • Your expectation of what is "satisfactory" is not correct. A CRC has the property you expect only if it has a zero initialization and no exclusive-or of the result. However the standard CRC-32 that you requested, crc_32_type initializes the CRC register with 0xffffffff, and exclusive-ors the result with 0xffffffff.

    However you will always get the same constant when you take the CRC of the message concatenated with the message's CRC (assuming that you order the bytes of the CRC correctly). That constant is 0x2144df1c for this particular CRC, and is the CRC of four zero bytes.

    It is common for CRC's to be defined in this way, so that the CRC of a string of zeros is not zero. Since the initialization and exclusive-or are the same, the CRC of the empty set is conveniently zero.

    What you should be doing is simply computing the CRC on the message without the CRC, and compare that to the transmitted CRC. That is what is normally done, and applies to all message hashes in general.