校驗和
校驗和是用於檢測傳輸過程中可能產生的錯誤,將其置於資料後,隨資料一同傳送,接收端通過同樣的演算法進行檢查,若正確就接受,錯誤就丟棄
校驗和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);
}
}
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.最後返回校驗和,是一個二進位制的反碼