[英]Checking CRC using boost library does not give satisfactory result
我正在使用boost crc庫來計算112位(80位數據+ 32位crc)位集的32位crc。 為了進行測試,我將所有80個數據位都重置為0。crc的計算似乎可以正常工作,但是當我將計算出的crc附加到數據中並再次計算crc時,我得到的值>0。但是我期望一個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
所以出了點問題,但是呢? 有任何想法嗎 ?
提前致謝。
您對“滿意”的期望是不正確的。 CRC僅在初始化為零且沒有結果異或的情況下,才具有您期望的屬性。 但是,您請求的標准CRC-32 crc_32_type
使用0xffffffff
初始化CRC寄存器,並使用0xffffffff
對結果進行異或運算。
但是,當您將消息的CRC與消息的CRC串聯在一起時,您將始終獲得相同的常量(假設您正確地對CRC字節進行排序)。 對於此特定CRC,該常數為0x2144df1c
,並且是四個零字節的CRC。
通常以這種方式定義CRC,以便零字符串的CRC不為零。 由於初始化和異或相同,因此空集的CRC通常為零。
您應該做的就是簡單地計算不帶CRC的消息上的CRC,並將其與傳輸的CRC進行比較。 這通常是完成的,並且通常適用於所有消息哈希。
首先,就像評論者說的那樣,一旦檢查了總和,就不要包括CRC位。 我建議做一個輔助函數來檢查n
位(在這種情況下為80)。
其次,考慮將代碼重構為可讀並表達意圖:
#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
調用,但請參見如何將位集轉換為字節/ uint8數組?
如果要在CRC校驗中包括CRC(我認為這是正確的技術),則預期結果始終為零。 不是發送的CRC。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.