1. 程式人生 > >校驗和計算方法

校驗和計算方法

return 增加 ron cksum 代碼 sizeof 內容 設置 strong

1.說明:

  [1]校驗和覆蓋的內容:

    IP校驗和:IP首部。

    ICMP校驗和:ICMP首部+ICMP數據;

    UDP、TCP校驗和:首部+數據+12個字節偽首部(源IP地址、目的IP地址、協議、TCP/UDP包長)。

2.計算校驗和的步驟:

  [1]把校驗和字段設置為0。

  [2]把需要校驗的數據看成以16位為單位的數字組成,依次進行二進制反碼求和。

  [3]把得到的結果存入校驗和字段中。

  另外UDP、TCP數據報的長度可以為奇數字節,因為計算時是16位為單位,所以此時計算校驗和時需要在最後增加一個填充字節0(只是計算校驗和用,不發送出去)。

3.接收端校驗校驗和步驟:

  [1]把需要校驗的內容(包括校驗和字段)看成以16位為單位的數字,依次進行二進制反碼求和,如果結果是0表示正確,否則表示錯誤。

4.二進制反碼求和步驟:

  [1]二進制反碼求和,就是先把這兩個數取反,然後求和,如果最高位有進位,則向低位進1。

  [2]另外,先取反後相加與先相加後取反,得到的結果是一樣的。因此實現代碼都是先相加,最後再取反。

5.實現代碼:

static inline uint16_t check_sum(const uint16_t *buffer, int size)
{
    unsigned long cksum = 0;
    
    //16位為單位數字相加
while(size>1){ cksum += *buffer++; size -= sizeof(uint16_t); } //長度奇數情況 if(size) cksum += *((unsigned char *)buffer); //高位有進位,進位到低位,下面兩行代碼保證了高16位為0。 cksum = (cksum>>16) + (cksum&0xffff); cksum += (cksum>>16); //最後取反 return
(uint16_t)(~cksum); }

校驗和計算方法