我正在使用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
出了问题,但是什么?有什么想法吗?
提前致谢。
答案 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。