分組校驗和的java實現
阿新 • • 發佈:2019-02-12
分組校驗和的演算法用在了很多分組的計算中。現在只針對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;
}
}