簡體   English   中英

使用Boost庫檢查CRC效果不理想

[英]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)。

其次,考慮將代碼重構為可讀並表達意圖:

生活在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調用,但請參見如何將位集轉換為字節/ uint8數組?

如果要在CRC校驗中包括CRC(我認為這是正確的技術),則預期結果始終為零。 不是發送的CRC。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM