1. 程式人生 > >java CRC16校驗,原版C++,改編成java

java CRC16校驗,原版C++,改編成java

 
/*
 * crc校驗,輸入一個數組,返回一個數組,返回的陣列比原陣列
 * 多了兩個位元組,也就是兩個校驗碼,低位元組在前,高位元組在後.
 */
public class CRC16 {
 public static int[] crc(int[] data){
  int[] temdata=new int[data.length+2];
  //unsigned char alen = *aStr – 2;   //CRC16只計算前兩部分      
   int xda , xdapoly ;          
   int i,j, xdabit ;           
   xda = 0xFFFF ; 
  xdapoly = 0xA001 ; // (X**16 + X**15 + X**2 + 1)  
  for(i=0;i<data.length;i++)        
  {        
  xda ^= data[i] ;
  for(j=0;j<8;j++) {        
   xdabit =( int )(xda & 0x01) ;        
   xda >>= 1 ;
  if( xdabit==1 )
   xda ^= xdapoly ;
   }       
  }   
  System.arraycopy(data, 0, temdata, 0, data.length);
  temdata[temdata.length-2] = (int)(xda & 0xFF) ;          
  temdata[temdata.length-1] = (int)(xda>>8) ;    
  return temdata;
  }

//這個主函式用來測試用的
 public static void main(String args[]){
  int[] data={12,25,1,4,10,5,47,2,45,2,3,4,7,5,6,2,45};
  int[] d1=crc(data);
  for(int i=0;i<d1.length;i++)
   System.out.print(d1[i]+" ");
  System.out.println();
  int[] d2=crc(d1);
  for(int i=0;i<d2.length;i++)
   System.out.print(d2[i]+" ");
 }

}

==================================================================================

下面是C++的演算法和參考原始碼;

4 校驗碼      
CRC碼由傳送端計算,放置於傳送資訊報文的尾部。接收資訊的裝置再重新計算接收到資訊報文的CRC,比較計算得到
的CRC是否與接收到的相符,如果兩者不相符,則表明出錯。       
校驗碼的計算多項式為(X16 + X15 + X2 + 1)。       
具體CRC16碼的
計算方法是:        
1.預置1個16位的暫存器為十六進位制FFFF(即全為1);稱此暫存器為CRC暫存器;      
2.把第一個8位二進位制資料 (既通訊資訊幀的第一個位元組)與16位的CRC暫存器的低8位相異或,把結果放於CRC暫存器;      
3.把CRC暫存器的內容右移一 位(朝低位)用0填補最高位,並檢查右移後的移出位;      
4.如果移出位為0:重複第3步(再次右移一位);         
   如果移出位為1:CRC暫存器與多項式A001(1010 0000 0000 0001)進行異或;      
5.重複步驟3和4,直到右移8次,這樣整個8位資料全部進行了處理;  
6.重複步驟2到步驟5,進行通訊資訊幀下一個位元組的處理;      
7.將該通訊資訊幀所有位元組按上述步驟計算完成後,得到的16位CRC暫存器的高、低位元組進行交換;      
8.最後得到的CRC暫存器內容即為:CRC碼。     

參考演算法的C語言實現如下。以下程式
計算一個報文的CRC16並填入報文最後兩位元組。      
void CRC16( unsigned char *aStr ){             
unsigned char alen = *aStr – 2;   //CRC16只計算前兩部分      
unsigned int xda , xdapoly ;          
unsigned char i,j, xdabit ;           
 xda = 0xFFFF ;       
xdapoly = 0xA001 ; // (X**16 + X**15 + X**2 + 1)           
for(i=0;i<alen;i++)        
{        
xda ^= aStr[i] ;        
for(j=0;j<8;j++) {        
 xdabit =(unsigned char )(xda & 0x01) ;        
 xda >>= 1 ;         
if( xdabit )
 xda ^= xdapoly ;  
 }       
}              
aStr[alen-2] = (unsigned char)(xda & 0xFF) ;          
aStr[alen-1] = (unsigned char)(xda>>8) ;      
}

===============================================================================

以程式碼僅供參考,如有不明白或建議請聯絡我,共同交流,email:[email protected]

另外提供一個網上找的java crc校驗的源程式,我沒怎麼研究,

import java.io.IOException;
 
public class CRC16Checker {
 
            private static int[] index = new int[] { 16, 15, 2, 0 };
 
            private static int[] getBinary(String text) {
                        StringBuffer num = new StringBuffer();
                        String s; char ch;
                        for (int i = 0; i < text.length(); i++) { // Change each char to binary code.
                                    s = Integer.toBinaryString(text.charAt(i));
                                    // If the code is less than 8 bit, make it as 8 bit.
                                    for (int j = 8 - s.length(); j > 0; j--) num.append(0);
                                    num.append(s);
                        }
                        int len = num.length();
                        int[] code = new int[len];
                        for (int i = 0; i < len; i++) // Change each 0/1 char to int.
                            code[i] = Character.getNumericValue(num.charAt(i));
                        return code;
            }
 
            private static String toHex(int[] num) {
                        StringBuffer hex = new StringBuffer(num.length / 4);
                        char[] ch = new char[4];
                        for (int i = 0; i < num.length;) {
                            // Change each 0/1 int to char.
                                    ch[0] = Character.forDigit(num[i++], 2);
                                    ch[1] = Character.forDigit(num[i++], 2);
                                    ch[2] = Character.forDigit(num[i++], 2);
                                    ch[3] = Character.forDigit(num[i++], 2);
                                    // Change each 4-bit-code to hex number.
                                    hex.append(Integer.toHexString(Integer.parseInt(String.valueOf(ch), 2)));
                        }
                        return hex.toString();
            }
 
// CRC codes main process
            public static int[] makeCRCCodes(int[] sourceCodes, int[] multinomial) {
                        // The lenght of CRC code is N bits longer than source code. The codes
                        // from 0 to sourceLength are same as the source. N bits after source
                        // are the CRC codes. N is decided by the multinomial.
                        // CRC碼陣列總長為原碼長加上校驗碼碼長。陣列前部存放原碼。校驗碼存放在陣列
                        // 最後的N位。校驗碼長度決定於生成多項式陣列0位置上的元素。
                        int sourceLength = sourceCodes.length;
                        int codesLength = sourceLength + multinomial[0];
                        int[] crcCodes = new int[codesLength];
                        // Copy source code from 0 to sourceLength. 拷貝原碼。
                        System.arraycopy(sourceCodes, 0, crcCodes, 0, sourceLength);
                        int temp, pos;
                        // Division system. 除法器。
                        for (int i = 0; i < sourceLength; i++) {
                                    // Count value of the input adding the first register.
                                    // 用第i位原碼和第一個暫存器值模二加。
                                    temp = (crcCodes[sourceLength] + sourceCodes[i]) % 2;
                                    // Move registers forwards from (1, length) to (0, length - 1).
                                    // 第二個暫存器及以後的所有暫存器值前移1位。
                                    System.arraycopy(
                                                crcCodes, sourceLength + 1, crcCodes, sourceLength, multinomial[0] - 1);
                                    // Set the last register with counted value.
                                    // 最後一個暫存器值存放計算好的輸入值。
                                    crcCodes[codesLength - 1] = temp;
                                    // Count other registers. 按生成多項式的值算出位置,模二加出該暫存器的值。
                                    for (int j = index.length - 2; j > 0; j--) {
                                                pos = codesLength - multinomial[j] - 1;
                                                crcCodes[pos] = (crcCodes[pos] + temp) % 2;
                                    }
                        }
                        return crcCodes;
            }
 
            public static void main(String[] args) throws IOException {
                        System.out.print("Input hex data :");
                        StringBuffer buf = new StringBuffer();
                        char ch = (char) System.in.read();
                        while (ch != '/r' && ch != '/n') {
                                    buf.append(ch);
                                    ch = (char) System.in.read();
                        }
                        // Get binary codes.
                        int[] b = CRC16Checker.getBinary(buf.toString());
                        // Make CRC codes.
                        b = CRC16Checker.makeCRCCodes(b, CRC16Checker.index);
                        // Output code as binary number.
                        for (int i = 0; i < b.length;) {
                                    for (int j = 0; j < 4; j++, i++) System.out.print(b[i]);
                                    System.out.print(' ');
                        }
                        System.out.println();
                        // Output code as hex number.
                        System.out.println("The CRC16 code is :" + CRC16Checker.toHex(b));
            }
}

相關推薦

java CRC16原版C++編成java

 /* * crc校驗,輸入一個數組,返回一個數組,返回的陣列比原陣列 * 多了兩個位元組,也就是兩個校驗碼,低位元組在前,高位元組在後. */public class CRC16 { public static int[] crc(int[] data){  int[] t

JAVA CRC16碼計算

package com.hcs.lqjc.controller.dongDaHengFeng.ModBus.utils; /** * @author lwt * @date 2018-06-26 * * CRC16校驗碼計算 * <p> * (1).

Modbus CRC16演算法--查表法(已經過本人測試工作良好)

程式碼如下: uchar auchCRCHi[]= { 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0

java程式碼手機號帶區號固定電話和400型別的固定電話

public class Tesyt {public static void main(String[] args) { //isPhoneNumberValid("0731-6296363"); //isPhoneNumberValid("0731-62963636");

Java EMAIL格式方法真為正確

/** * 校驗EMAIL格式,真為正確 * * @author * @date 2017-7-19 * @param email * @return true 為格式正確 false

java modbus crc16碼 socket給傳送的資料新增crc

首先crc16校驗碼的生成的原理在上一篇部落格裡面已經說過了; 前提:xframe配置京金華伺服器的埠號,繫結ip地址和埠號 程式要實現什麼? 這個程式主要實現的是伺服器傳送資料到客戶端,然後客戶端傳送資料到伺服器端; 是一問一答的形式; 只有伺服器傳送,客戶端才會應答 傳送

forms元件(註冊使用者講解)(欄位功能渲染模板功能渲染錯誤資訊功能區域性鉤子渲染錯誤資訊全域性鉤子渲染錯誤資訊)

forms元件 from django import forms class Myforms(forms.Form): name = forms.CharField(max_length=8,min_length=3 ,label='使用者名稱',

寫給自己的話學院派 C 轉 實用派Java

本人計算機專業出身,學校學習過C / VC++. 寫過很一般的程式碼, 刷過北大百鍊 ACM 的部分試題。學過資料結(還可以),資料庫(學的一般會用sql)。用 c指標連結串列構建過二叉樹實現過哈夫曼編碼加解密。 寫程式碼不是問題,就是框架不熟悉。 然而有著這些基礎,來到求職市場 卻突然感覺啥也沒用一樣。大

Katalon 元素CSS樣式如頁面元素的文字顏色、字型大小等【WebUI自動化測試】

當我們做UI自動化測試時,可能會有這樣的需求,檢驗某個元素的文字顏色、字型大小等等,我們可以用WebUI.getCSSValue(TestObject to, String css)方法,獲取一個元素物件的CSS樣式。 element_colour = WebUI.getCSSValue

angularJs 表單 (手機號使用者名稱密碼等)

<!DOCTYPE html> <html ng-app="angularFormCheckModule">     <head>         <meta charset="UTF-8">

Java記憶體模型FAQ(二) 其他語言C++也有記憶體模型嗎?

譯者:Alex 大部分其他的語言,像C和C++,都沒有被設計成直接支援多執行緒。這些語言對於發生在編譯器和處理器平臺架構的重排序行為的保護機制會嚴重的依賴於程式中所使用的執行緒庫(例如pthreads),編譯器,以及程式碼所執行的平臺所提供的保障。 原文 Do other languag

備份兩不誤MySQL自動備份還原設計詳解

作者介紹 龐闊,優朋普樂傳媒運維基礎部經理。負責資料庫運營管理及平臺設計開發,監控設計改進,問題跟蹤處理,機房網路維護管理,目前四個專利已在專利局申請中。擅長資料庫運維管理及Shell、Perl、PHP編寫。 背景 最近關於資料庫故障出現的問題較多,不論大小公司對資料的備份要求都很高,但對校驗資料備

串列埠通訊方式(evenoddspacemark)

奇校驗 (odd parity):如果字元資料位中"1"的數目是偶數,校驗位為"1",如果"1"的數目是奇數,校驗位應為"0"。(校驗位調整個數) 偶校驗 (even parity):如果字元資料位中"1"的數目是偶數,則校驗位應為"0",如果是奇數則為"1"。(校驗位調整個數) mark parit

easyui的validate必填項空格問題。

問題:專案名稱等 為必填項,輸入空格,依然儲存成功;      解決:   方法一: 修改reqiuired的校驗。 方法二: 自定義的validate.js.  isBlank: {      

easyui 輸入框 限制字型長度以及型別。。。

文件說明:設定屬性 validtype, 可String 和array 文字: <input id="desc" class="easyui-textbox" data-options="multiline:true,validType:'length[1,60]'"

java 輸入3個數a,b,c按大小順序輸出。

題目: 輸入3個數a,b,c,按大小順序輸出。 程式碼: import java.util.Scanner; public class lianxi34 { public static

java實現CRC16碼生成

public static String crc16(String gprsstr) { try { int crc; int strlength, r; byte sbit; int tc; strlength = gprsstr.len

關於xmlspy對xml Schemaxml文件生成指定xml格式資料的操作

對傳入xml格式的資料,往往需要轉換成指定格式的資料,這時候需要xml Schema來進行實現。傳入報文如下:Xml Schema準換模板:使用xmlSpy進行驗證,轉換後的模板為:關於xmlSpy的使用:1.將輸入xml文件和轉換xslt模板在xmlSpy中開啟2.顯示介面

微信小程式業務域名配置:檔案驗證失敗請下載檔案上傳到伺服器指定的目錄

1.校驗檔案內容錯誤。校驗檔案內容一般是非HTML資料,如果下載下來的校驗檔案內容為HTML資料,一般為登入態過期。請重新登入小程式下載校驗檔案。 2.https證書過期。請確保https證書處於有效期內。 3.使用curl 測試連結,確保curl能夠正常訪問連結。