CRC 16検証アルゴリズムのJava実装

8814 ワード

CRC 16検証アルゴリズムの概要
CRCとは、巡回冗長検査コード(Cyclic Redundency Check[1])であり、データ通信分野で最も一般的な誤りチェックコードであり、情報フィールドと検査フィールドの長さを任意に選択できることを特徴とする.循環冗長検査(CRC)は、データを多項式計算し、結果をフレームの後ろに添付し、受信装置も同様のアルゴリズムを実行して、データ伝送の正確性と完全性を保証する.
Crc 16 Util説明
CRC 16には、Modbus CRC 16の検証アルゴリズムに基づくjavaで実現される様々な実装アルゴリズムがあります.他のプロトコルに基づくアルゴリズムであれば、getCrc 16()における実装を変更するだけでよい.get Crc 16()は、コアアルゴリズムであり、検証コードbyte配列を取得します.int ToBytes()算出したintタイプをbyte配列に変換し、下位は前、高位は後となります.高い地位の順序を変えるには、方法の配列の順序を変えるだけです.get Data();ソースデータと検証コードの組み合わせbyte配列を取得して、byte配列に入ることができます.16進数文字配列に入ることもできます.byteTo 16 String()byteまたはbyte配列を16進数文字に変換します.ここでは主に観察アルゴリズムの結果をテストするために使用します.
ツールソース
/**
 *   Modbus CRC16        
 */
public class Crc16Util {

    /**
     *             byte  
     * @param strings             
     * @return
     */
    public static byte[] getData(String...strings) {
        byte[] data = new byte[]{};
        for (int i = 0; iint x = Integer.parseInt(strings[i], 16);
            byte n = (byte)x;
            byte[] buffer = new byte[data.length+1];
            byte[] aa = {n};
            System.arraycopy( data,0,buffer,0,data.length);
            System.arraycopy( aa,0,buffer,data.length,aa.length);
            data = buffer;
        }
        return getData(data);
    }
    /**
     *             byte  
     * @param aa     
     * @return
     */
    private static byte[] getData(byte[] aa) {
        byte[] bb = getCrc16(aa);
        byte[] cc = new byte[aa.length+bb.length];
        System.arraycopy(aa,0,cc,0,aa.length);
        System.arraycopy(bb,0,cc,aa.length,bb.length);
        return cc;
    }
    /**
     *      byte  ,  Modbus CRC16     
     */
    private static byte[] getCrc16(byte[] arr_buff) {
        int len = arr_buff.length;

        //    1   16           FFFF,        CRC   。
        int crc = 0xFFFF;
        int i, j;
        for (i = 0; i < len; i++) {
            //      8          16    CRC      8     ,       CRC   
            crc = ((crc & 0xFF00) | (crc & 0x00FF) ^ (arr_buff[i] & 0xFF));
            for (j = 0; j < 8; j++) {
                //   CRC           (    )  0      ,           
                if ((crc & 0x0001) > 0) {
                    //        1, CRC       A001    
                    crc = crc >> 1;
                    crc = crc ^ 0xA001;
                } else
                    //        0,      
                    crc = crc >> 1;
            }
        }
        return intToBytes(crc);
    }
    /**
     *  int   byte  ,    ,    
     *                
     */
    private static byte[] intToBytes(int value)  {
        byte[] src = new byte[2];
        src[1] =  (byte) ((value>>8) & 0xFF);
        src[0] =  (byte) (value & 0xFF);
        return src;
    }
    /**
     *                
     */
    public static String byteTo16String(byte[] data) {
        StringBuffer buffer = new StringBuffer();
        for (byte b : data) {
            buffer.append(byteTo16String(b));
        }
        return buffer.toString();
    }
    /**
     *              
     * int byte   
     * [128,255],0,[1,128)
     * [-128,-1],0,[1,128)
     */
    public static String byteTo16String(byte b) {
        StringBuffer buffer = new StringBuffer();
        int aa = (int)b;
        if (aa<0) {
            buffer.append(Integer.toString(aa+256, 16)+" ");
        }else if (aa==0) {
            buffer.append("00 ");
        }else if (aa>0 && aa<=15) {
            buffer.append("0"+Integer.toString(aa, 16)+" ");
        }else if (aa>15) {
            buffer.append(Integer.toString(aa, 16)+" ");
        }
        return buffer.toString();
    }
}
テストコード
public static void main(String[] args) {

    byte[] dd = Crc16Util.getData("FE", "05","66");
    String str = Crc16Util.byteTo16String(dd).toUpperCase();
    System.out.println(str);
}
印刷結果:FE 05 66 4 A