JAVA實(shí)現(xiàn)CRC16校驗(yàn)
要求:
CRC循環(huán)冗余錯(cuò)誤校驗(yàn)計(jì)算方法
CRC-16C(循環(huán)冗余錯(cuò)誤校驗(yàn))生成CRC-16校驗(yàn)字節(jié)的步聚如下:
(1)裝入一個(gè)16位寄存器,所有數(shù)位均為1。
(2)該16位寄存器的高位字節(jié)與開始8位字節(jié)進(jìn)行“異或”運(yùn)算。運(yùn)算結(jié)果放入這個(gè)16位寄存器。
(3)把這個(gè)16位寄存器向右移1位。
(4a)若向右(標(biāo)記位)移出的數(shù)位是1,則生成多項(xiàng)式1010000000000001和這個(gè)寄存器進(jìn)行“異或”運(yùn)算。
(4b)若向右移出的數(shù)位是0,則返回(3)。
(5)重處處(3)和(4),直至移出8位。
(6)另外8位與該16位寄存器進(jìn)行“異或”運(yùn)算。
(7)重處處(3)-(6),直至該報(bào)文所有字節(jié)均與16位寄存器進(jìn)行“異或”運(yùn)算,并移位8次。
(8)這個(gè)16位寄存器的內(nèi)容即2字節(jié)CRC錯(cuò)誤校驗(yàn)。
private byte[] CRC=new byte[2];
byte data;
byte[] reg=new byte[2];
byte[] ploy=new byte[2];
byte Op;
public CRC(byte[] source){
//初始化多項(xiàng)式
int temp=0xA001;
ploy=InttoByteArray(temp,2);
//初始化寄存器
temp=0xFFFF;
reg=InttoByteArray(temp,2);
for(int i=0;i<source.length;i++){
//獲取數(shù)據(jù)
data=source[i];
//與寄存器中數(shù)據(jù)進(jìn)行異或操作
reg[1]=(byte) (reg[1]^data);
//移動(dòng)數(shù)據(jù)
for(int j=0;j<8;j++){
//獲取數(shù)據(jù)的最后一位,即被移動(dòng)出的數(shù)據(jù)判斷是否與多項(xiàng)式異或
Op=reg[0];
//右移一位
reg=InttoByteArray(ByteArraytoInt(reg)>>1,2);
//如果移出數(shù)據(jù)為1
if((Op&0x01)==1){
//與多項(xiàng)式進(jìn)行異或操作
reg[0]=(byte) (reg[0]^ploy[0]);
reg[1]=(byte) (reg[1]^ploy[1]);
}
}
}
CRC=reg;
}
public byte[] getCRC() {
return CRC;
}
//格式化輔助函數(shù)
private static byte[] InttoByteArray(int iSource, int iArrayLen) {
byte[] bLocalArr = new byte[iArrayLen];
for ( int i = 0; (i < 4) && (i < iArrayLen); i++) {
bLocalArr[i] = (byte)( iSource>>8*i & 0xFF );
}
return bLocalArr;
}
private static int ByteArraytoInt(byte[] bRefArr) {
int iOutcome = 0;
byte bLoop;
for ( int i =0; i<bRefArr.length ; i++) {
bLoop = bRefArr[i];
iOutcome+= (bLoop & 0xFF) << (8 * i);
}
return iOutcome;
}
}
另外,好像CRC算法也有好多種,我就沒在網(wǎng)上找到用戶要求的這種算法。貌似這個(gè)算法是Modbus協(xié)議中的CRC校驗(yàn)方式。有待確認(rèn)。
posted on 2008-07-24 12:11 SeesSea 閱讀(8742) 評(píng)論(2) 編輯 收藏 所屬分類: JAVA