Java實現循環冗餘碼(CRC)生成算法
一、CRC生成算法原理
1.1 多項式編碼
多項式編碼(polynomial code),也稱爲CRC(cyclic redundancy check,循環冗餘校驗碼),多項式編碼的思想是:將位串看成是係數爲0或1的多項式。CRC校驗保護的單位是數據塊。數據塊的大小根據實際情況而定。每一個數據塊均被看作是一個二進制多項式,即所有係數均爲二進制(即1或0)的多項式。
當使用多項式編碼時,發送方和接受方必須預先商定一個生成多項式(generator polynomial)G(x)。生成多項式的最高位和最低位必須爲1。
1.2 CRC原理
將待發送的位串看成係數爲 0 或 1 的多項式
收發雙方約定一個生成多項式 G(x)
(其最高階和最低階係數必須爲1),發送方用位串及 G(x)進行某種運算得到校驗和,並在幀的末尾加上校驗和,使帶校驗和的幀的多項式能被 G(x) 整除; 接收方收到後,用 G(x) 除多項式,若有餘數,則傳輸有錯。
1.3 CRC校驗和計算法
1.3.1 若生成多項式 G(x) 爲 r 階(即r+1位位串),原幀爲 m 位, 其多項式爲 M(x),則在原幀後面添加 r 個 0,即循環左移r位,幀成爲 m+r 位,相應多項式成爲 xrM(x) ;
1.3.2按模2除法用 G(x)對應的位串去除對應於xrM(x) 的位串, 得餘數 R(x);
1.3.3 按模2減法(即模2加)從對應於 xrM(x) 的位串中減去(加上)餘數 R(x),結果即傳送的帶校驗和的幀多項式T(x)。 T(x)=xrM(x)+R(x)
1.3.4 例子
二、代碼及運行結果
2.1 關鍵代碼
/**
* @Description TODO 計算循環冗餘碼 需注意多項式位數與幀位數之和不得超過32位!
* @version V1.0
*
*/
public class CrcAlgorithm {
public static void main(String[] args) {
print("請輸入二進制數據: ");
Scanner sc = new Scanner(System.in);
String dataStr = sc.next();
print("請輸入多項式係數: ");
String gxStr = sc.next();
sc.close();
//獲取二進制幀的位數
int dataStrLen = dataStr.length();
//獲取多項式位數
int gxStrLen = gxStr.length();
//將二進制的字符串變爲整型
int data = toInt(dataStr);
//將多項式的字符串變爲整型
int gx = toInt(gxStr);
//算出原始數據補零後的總位數
int sum = dataStrLen+gxStrLen-1;
//計算2的sum-1次冪
BigInteger bi = new BigInteger("2");
//將2的sum-1次冪轉換爲int型
int flag = bi.pow(sum-1).intValue();
//原始幀低位補零
data = data<<(gxStrLen-1);
//多項式低位補零,使其與補零後的幀位數一致,以便異或
gx = gx<<(dataStrLen-1);
//循環dataStrLen次
for(int i=0; i<(dataStrLen);i++){
//判斷補零後的幀最高位爲1還是零
if((data&flag)!=0) {
data = data^gx;
gx = gx>>1;
}else {
gx = gx>>1;
}
//flag最高位的1右移
flag = flag>>1;
}
String crc = Integer.toBinaryString(data);
//解決Java輸出二進制時略去高位零的問題
while(crc.length()<(gxStrLen-1)) {
crc = "0"+crc;
}
print("冗餘碼:"+crc);
}
}
2.2 運行結果
2.3 源代碼鏈接: CRC算法Java實現源代碼
三 待改進之處
由於Java int 類型位寬爲32位,所以本算法多項式位數與幀位數之和不得超過32位!如果多項式位數與幀位數之和超過32位,可將數據類型改爲long型。此時多項式位數與幀位數之和不得超過64位。因爲java long最大長度爲64位,若需更大位寬,參考java.math.BigDecimal