1. 程式人生 > >分組校驗和的java實現

分組校驗和的java實現

分組校驗和的演算法用在了很多分組的計算中。現在只針對IP分組而言,IP分組只對IP分組頭進行計算,演算法如下:
1、計算校驗和
1)初始時,將校驗和域都設定為0
2)每16bit做二進位制反碼求和。
3)得到的結果取反便是檢驗和
2、驗證校驗和
1)將IP分組頭中每16bit分為一小組,進行二進位制反碼求和
2)檢視結果是否為0,如果為0,表示正確,否則表示錯誤。

何為二進位制反碼和?
下面是我個人理解:我們知道計算機中對數字有三種表示方法:原碼、反碼和補碼,比如對8而言,1000為其原碼,0111為其反碼,1000為其補碼。通常,計算機儲存數字時都以補碼形式儲存。因此我們平時所做的加減法也可以說是二進位制補碼和。而反碼求和,自然就是以反碼錶示的數字進行求和。比如8+9,補碼(原碼)求和:1000 + 1001 = 0001(17),反碼求和0111 + 0110 = 1101。
經過總結規律,可以發現反碼求和的結果滿足如下規律:原碼和+原碼和高位移除之後再取反的結果。0001+0001(溢位) = 0010,取反為1101。

由於加法具有結合律,因此可以先對整個陣列做原碼加法,然後再取反

package com.IP;

/**
 * Created by dave on 2016/2/19.
 */
//計算頭部校驗和
public class HeaderCheckSum {
    public String caculate(int[] data){//data以16bit形式傳入,如0xabcd
        int sum = 0;
        for(int i = 0;i<data.length;i++){
            sum += data[i];
        }
        for
(int i = 0;i<2;i++) {//這裡迴圈兩次,是因為sum溢位後的高位與低16bit相加之後仍然可能會溢位,所以需要再重複一次,那麼會不會再次溢位呢?肯定不會,不妨試一試。 int low = sum & 0xffff; int high = (sum >> 16) & 0xffff; sum = low + high; } //16進製表示 String hexString = Integer.toHexString(~sum & 0xffff
); System.out.println("校驗和:"+hexString); return hexString; } //判斷是否有效 public boolean isValid(int[] data){ int sum = 0; for(int tmp:data){ sum += tmp; } for(int i = 0;i<2;i++){ int low = sum & 0xffff; int high = (sum >> 16)&0xffff; sum = low + high; } boolean res = false; if((~sum & 0xffff) == 0) res = true; System.out.println("valid:"+res); return res; } }