1. 程式人生 > >校驗和

校驗和

校驗和是用於檢測傳輸過程中可能產生的錯誤,將其置於資料後,隨資料一同傳送,接收端通過同樣的演算法進行檢查,若正確就接受,錯誤就丟棄

校驗和C原始碼:


反校驗:

char _check_sum(const unsigned char *data, int len)
{
int i = 0;
unsigned char sum = 0;

if(len <= 0)
{
return TR_FAILURE;
}

for(i = 0; i < len; i++)
{
sum += data[i];
}


//TR_PRINTF("biao:check sum = %d\n",sum);


return sum;
}

校驗和:

char _checksum_8(unsigned char *buf,int len)

{
int i = 0;
int sum = 0;

for (i = 0; i < len; i++)
{
sum += buf[i];//將每個數相加
}

if(sum>0xff)
{
sum=~sum;
sum+=1;
}

//TR_PRINTF("biao:sum = %x\n",(sum&0xff));
return (sum&0xff); 
}


===================================================


unsigned short checksum(unsigned char *buf,int len)
{
        unsigned int sum=0;          //1
        unsigned short *cbuf;        //2
        cbuf=(unsigned short *)buf;    //3


        while(len>1)                        //4
        {
                sum+=*cbuf++;
                len-=2;
        }
        if(len)                               //5
        {
                sum+=*(unsigned char *)cbuf;
        }


        while(sum>>16)     //6
        {
                sum=(sum>>16)+(sum&0xffff);
        }

return (~sum);     //7
}


1.定義檢驗和變數,32位的 int型

2.定義接受的字元,16位的short int 型,因為校驗和就是一個基於16位的反碼計算原理,計算機制為1的補碼,對稱的系統,ffff和0000分別為-0和+0,afff和7ffff分別是-32767和+32767,這與我們平時遇到的2的補碼機制不同

為什麼要基於1的補碼並進行反碼求和機制?

因為考慮到大端和小端位元組序的問題,在不同架構的處理器的儲存方式不同,如果用常規的加法,接收端和傳送端可能由於處理器架構不同會出現校驗和的不同,但用反碼求和,不管是大端還是小端,最終得到的結果都一樣,不會影響到最終的校驗和。

3.將8位的char型別轉換成16位的short型 

4.進行校驗和的加法,都是基於16位的,每次進行16位移動

5.若len為奇數,要加上最後的8bit,也就是最後一個位元組

6.將得到的校驗和右移16位,這裡是無符號的,也就是算術右移,後面一句也就是將sum的高16位和低16位做加法,這就是1的補碼機制,最高位進位加到最低位。

7.最後返回校驗和,是一個二進位制的反碼