1. 程式人生 > >累加和校驗演算法(CheckSum演算法)

累加和校驗演算法(CheckSum演算法)

因為外界總會對電路存在或多或少的干擾,對於數字訊號,很可能導致傳輸的資料出現千差萬別。對於很多需要傳輸資料的場合,尤其是一些資料可能會影響一些硬體的動作(諸如嵌入式的一些裝置、機器人等),錯誤的資料可能會帶來一些隱性風險,想想都可怕。

由於本人是嵌入式相關領域的,平時玩的都是微控制器,當然微控制器的效能千差萬別,不過很多的效能都只能說是勉強夠用,畢竟成本考慮。

所以今天的校驗說法,比較簡單,但是有效,尤其是一些效能一般的硬體。

說道今日主角:累加和校驗演算法,又名CheckSum演算法。至於出處,這裡就不考究了。

這種演算法的實現:

傳送方:對要資料累加,得到一個數據和,對和求反,即得到我們的校驗值。然後把要發的資料和這個校驗值一起傳送給接收方。

接收方:對接收的資料(包括校驗和)進行累加,然後加1,如果得到0,那麼說明資料沒有出現傳輸錯誤。(注意,此處傳送方和接收方用於儲存累加結果的型別一定要一致,否則加1就無法實現溢位從而無法得到0,校驗就會無效)

還是舉個例子:

傳送方:要傳送0xA8,0x50,我們使用unsigned char(8位)來儲存累加和,即為0xF8(0b11111000),取反得到校驗和為0x07(0b00000111)。然後將這三個資料傳送出去。

接收方:如果接收正確,這三個資料的累加和就是(0b11111111),此時加1,則得到的結果為0(實際得到的應該是0b100000000,但是由於是使用unsigned char(8位)來儲存累加和,所以高位被擷取掉,只剩下了低八位的8個0).

由上面的例子,我們可以知道演算法的目的是:使累加和和校驗值相加得到一個二進位制下每一位都是1的結果,這個結果很明顯很好處理,這種演算法實現起來也很簡單,下面給出C語言的程式碼示例。

傳送方:以下是如何得到校驗值的程式碼,結果就是我們想要的校驗值。

U8 TX_CheckSum(U8 *buf, U8 len) //buf為陣列,len為陣列長度
{ 
    U8 i, ret = 0;

    for(i=0; i<len; i++)
    {
        ret += *(buf++);
    }
     ret = ~ret;
    return ret;
}

接收方:輸入已包含傳送發發來的校驗值,如果函式返回的值如果是0,說明資料正確。

U8 RX_CheckSum(U8 *buf, U8 len) //buf為陣列,len為陣列長度
{ 
    U8 i, ret = 0;

    for(i=0; i<len; i++)
    {
        ret += *(buf++);
    }
     ret = ret;
    return ret+1;
}