使用boost库检查CRC并不能给出满意的结果

时间:2015-07-15 17:24:07

标签: c++ boost crc bitset

我正在使用boost crc库来计算112位(80位数据+ 32位crc)位集的32位crc。为了测试,我将所有80个数据位重置为0.计算crc似乎工作正常,但是当我将计算出的crc附加到数据并再次计算crc时,我得到一个值>但我希望crc值正好为0.这是代码:

    // 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;

输出结果为:

    1326744236
    559431208

我预期的输出是:

    1326744236
    0

出了问题,但是什么?有什么想法吗?

提前致谢。

3 个答案:

答案 0 :(得分:1)

您对“满意”的期望是不正确的。只有初始化为零且没有异或结果时,CRC才具有您期望的属性。但是,您请求的标准CRC-32 crc_32_type使用0xffffffff初始化CRC寄存器,并将结果与​​0xffffffff进行异或。

但是,当您使用与消息的CRC连接的消息的CRC时,您将始终获得相同的常量(假设您正确地命令了CRC的字节)。对于这个特定的CRC,该常量是0x2144df1c,并且是四个零字节的CRC。

以这种方式定义CRC是很常见的,因此一串零的CRC不为零。由于初始化和异或相同,空集的CRC方便地为零。

您应该做的只是在没有CRC的情况下计算消息上的CRC,并将其与传输的CRC进行比较。这就是通常所做的,并且通常适用于所有消息哈希。

答案 1 :(得分:0)

首先,就像评论者说的那样,一旦检查了总和,就不要包括CRC位。我建议创建一个辅助函数来检查n位(在本例中为80)。

其次,考虑重构代码以使其具有可读性并表达意图:

<强> Live On Coliru

#include <iostream>
#include <string>
#include <bitset>
#include <algorithm>
#include <boost/crc.hpp>
#include <cassert>

template <size_t N>
uint32_t crc32_n(std::bitset<N> const& bs, size_t n) {
    assert(n <= N);

    std::string const s = bs.template to_string<char>();
    auto f = s.begin();

    return std::for_each(f, f+n, boost::crc_32_type{})();
}

int main() {
    std::bitset<112> b_data;

    // set some random data (above the first 32 bits that are for CRC)
    srand(time(0));
    b_data.set(rand()%80 + 32);

    auto const crc = crc32_n(b_data, 80);

    std::cout << crc                 << ":\t" << b_data << "\n";
    b_data |= crc;
    std::cout << crc32_n(b_data, 80) << ":\t" << b_data << "\n";
}

打印例如。

1770803766: 0000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000
1770803766: 0000000000000000000000000000000000000000000000000000000000000000000000010000000001101001100011000101001000110110

或(在另一次运行中)

2436181323: 0000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000
2436181323: 0000000000000000000000000000000000000000000000000000000000000000000000100000000010010001001101010010110101001011

我很想继续删除可疑的to_string来电,但请看How do I convert bitset to array of bytes/uint8?

答案 2 :(得分:0)

如果您要在CRC检查中包含CRC,我认为这是正确的技术,预期结果始终为零。不是传输的CRC。