CRC-16 (Modbus)校验码

来源:互联网 发布:邮箱注册淘宝流程 编辑:程序博客网 时间:2024/05/16 12:13

CRC16_MODBUS:多项式x16+x15+x5+1(0x8005),初始值0xFFFF,低位在前,高位在后,结果与0x0000异或。

参考学习网址:
1.CRC16常见几个标准的算法及C语言实现 - CSDN博客 http://blog.csdn.net/leumber/article/details/54311811
2.Java生成CRC16数据校验码 - 专注于大数据技术研究和应用 - CSDN博客 http://blog.csdn.net/fjssharpsword/article/details/53884915
3.Java CRC16校验 - CSDN博客 http://blog.csdn.net/trbbadboy/article/details/42145461/

具体代码:

使用

//"7E000560313233" (hex) ---> CRC-16 (Modbus) 0xBD53            String str16jinzhi = "7E000560313233";            byte[] str16jinzhiTobyte = CrcheckUtil.hexStringToBytes(str16jinzhi);            String crc16str = Make_CRC(str16jinzhiTobyte);            Log.d("ActImageList", "任意byte[] 计算得 crc16校验码:" + crc16str);//两个低位在前,两个高位在后            Log.d("ActImageList", "=================CRC-16 (Modbus)=====================");            int crc = CrcheckUtil.calcCrc16(str16jinzhiTobyte);            String str10to16 = String.format("0x%04x", crc);//10进制转换16正确            Log.d("ActImageList", "十进制数 crc16 转16进制:" + str10to16);            Log.d("ActImageList", "===================CRC-16 (Modbus)===================");            int result = CrcheckUtil.getCrc16(str16jinzhi);            Log.d("ActImageList", "计算得到十进制数crc校验码:" + result);            String result10to16 = String.format("0x%04x", result);            Log.d("ActImageList", "十进制数crc校验码 转16进制:" + result10to16);
/**     * CRC-16 (Modbus) :     * 计算产生校验码     * @param data 需要校验的数据     * @return 校验码     */    public static String Make_CRC(byte[] data) {        byte[] buf = new byte[data.length];// 存储需要产生校验码的数据        for (int i = 0; i < data.length; i++) {            buf[i] = data[i];        }        int len = buf.length;        int crc = 0xFFFF;//16位        for (int pos = 0; pos < len; pos++) {            if (buf[pos] < 0) {                crc ^= (int) buf[pos] + 256; // XOR byte into least sig. byte of                // crc            } else {                crc ^= (int) buf[pos]; // XOR byte into least sig. byte of crc            }            for (int i = 8; i != 0; i--) { // Loop over each bit                if ((crc & 0x0001) != 0) { // If the LSB is set                    crc >>= 1; // Shift right and XOR 0xA001                    crc ^= 0xA001;                } else                    // Else LSB is not set                    crc >>= 1; // Just shift right            }        }        String c = Integer.toHexString(crc);        if (c.length() == 4) {            c = c.substring(2, 4) + c.substring(0, 2);        } else if (c.length() == 3) {            c = "0" + c;            c = c.substring(2, 4) + c.substring(0, 2);        } else if (c.length() == 2) {            c = "0" + c.substring(1, 2) + "0" + c.substring(0, 1);        }        return c;    }

工具类

public class CrcheckUtil {    private static final char[] HEX_CHAR = {'0', '1', '2', '3', '4', '5',            '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};    private static final int POLYNOMIAL = /*0xA053;*//*0x0589*/0xA001;    /*    02 05 00 03 FF 00 的不同crc计算值:    CRC-16 0x127C    CRC-16 (Modbus)    0x097C 对应的多项式为 0xA001    CRC-16 (Sick)  0xE2F0    CRC-CCITT (XModem) 0xF2B8    CRC-CCITT (0xFFFF) 0xFCA8    CRC-CCITT (0x1D0F) 0xC386    CRC-CCITT (Kermit) 0xA63E    CRC-DNP    0x6E28*/    private static final int PRESET_VALUE = 0xFFFF;    public static String getHexString(int i){        String hexString = String.format("%04x",i);        return hexString;    }    /**     * @param data byte[]     * @return 低位在前,高位在后的16进制字符串     */    public static String getCrc16String(byte[] data){        StringBuilder builder = new StringBuilder();        String hex = getHexString(getCrc16(data));        builder.append(hex.substring(2));        builder.append(hex.substring(0,2));        return builder.toString();    }    /**     * @param data String     * @return 低位在前,高位在后的16进制字符串     */    public static String getCrc16String(String data){        StringBuilder builder = new StringBuilder();        String hex = getHexString(getCrc16(data));        builder.append(hex.substring(2));        builder.append(hex.substring(0,2));        return builder.toString();    }    /**     * @param data byte数组     * @return  CRC16校验得到的十进制int     */    public static int getCrc16(byte[] data){        System.out.println("\nCRC 16 calculation progress:\n");        int current_crc_value = PRESET_VALUE;        for (int i = 0; i < data.length; i++){            current_crc_value ^= data[i] & 0xFF;            for (int j = 0; j < 8; j++ ) {                if ((current_crc_value & 1) != 0) {                    current_crc_value = (current_crc_value >>> 1) ^ POLYNOMIAL;                }                else{                    current_crc_value = current_crc_value >>> 1;                }            }        }        return current_crc_value & 0xFFFF;    }    /**     * @param str 16进制字符串     * @return CRC16校验得到的十进制int     */    public static int getCrc16(String str){        byte[] data = hexStringToBytes(str);        System.out.println("\nCRC 16 calculation progress:\n");        int current_crc_value = PRESET_VALUE;        for (int i = 0; i < data.length; i++){            current_crc_value ^= data[i] & 0xFF;            for (int j = 0; j < 8; j++ ) {                if ((current_crc_value & 1) != 0) {                    current_crc_value = (current_crc_value >>> 1) ^ POLYNOMIAL;                }                else{                    current_crc_value = current_crc_value >>> 1;                }            }        }        return current_crc_value & 0xFFFF;    }    /**     * byte[] 转 16进制字符     *     * @param b     * @return     */    public static String printHexString(byte[] b) {        StringBuffer returnValue = new StringBuffer();        for (int i = 0; i < b.length; i++) {            String hex = Integer.toHexString(b[i] & 0xFF);            if (hex.length() == 1) {                hex = '0' + hex;            }            if (i % 2 == 0) {                returnValue.append(hex.toUpperCase() + "");            } else {                returnValue.append(hex.toUpperCase() + " ");            }        }        return returnValue.toString();    }    /**     * 方法一:     * byte[] to hex string     *     * @param bytes     * @return     */    public static String bytesToHexFun1(byte[] bytes) {        // 一个byte为8位,可用两个十六进制位标识        char[] buf = new char[bytes.length * 2];        int a = 0;        int index = 0;        for(byte b : bytes) { // 使用除与取余进行转换            if(b < 0) {                a = 256 + b;            } else {                a = b;            }            buf[index++] = HEX_CHAR[a / 16];            buf[index++] = HEX_CHAR[a % 16];        }        return new String(buf);    }    /**     * 方法二:     * byte[] to hex string     *     * @param bytes     * @return     */    public static String bytesToHexFun2(byte[] bytes) {        char[] buf = new char[bytes.length * 2];        int index = 0;        for(byte b : bytes) { // 利用位运算进行转换,可以看作方法一的变种            buf[index++] = HEX_CHAR[b >>> 4 & 0xf];            buf[index++] = HEX_CHAR[b & 0xf];        }        return new String(buf);    }    /**     * byte[]转换成16进制字符串     *     * @param src     * @return     */    public static String bytesToHexString(byte[] src) {        StringBuilder stringBuilder = new StringBuilder("");        if (src == null || src.length <= 0) {            return null;        }        for (int i = 0; i < src.length; i++) {            int v = src[i] & 0xFF;            String hv = Integer.toHexString(v);            if (hv.length() < 2) {                stringBuilder.append(0);            }            stringBuilder.append(hv);        }        return stringBuilder.toString();    }    /**     * @param b     *            字节数组     * @return 16进制字符串     * @throws     */    public static String bytes2HexString(byte[] b) {        StringBuffer result = new StringBuffer();        String hex;        for (int i = 0; i < b.length; i++) {            hex = Integer.toHexString(b[i] & 0xFF);            if (hex.length() == 1) {                hex = '0' + hex;            }            result.append(hex.toUpperCase());        }        return result.toString();    }    /**     * 16进制字符串转byte[]     *     * @param hexString     * @return     */    public static byte[] hexStringToBytes(String hexString) {        if (hexString == null || hexString.equals("")) {            return null;        }        hexString = hexString.toUpperCase();        int length = hexString.length() / 2;        char[] hexChars = hexString.toCharArray();        byte[] d = new byte[length];        for (int i = 0; i < length; i++) {            int pos = i * 2;            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));        }        return d;    }    private static byte charToByte(char c) {        return (byte) "0123456789ABCDEF".indexOf(c);    }    static byte[] crc16_tab_h = { (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0,            (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1,            (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0,            (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0,            (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40 };    static byte[] crc16_tab_l = { (byte) 0x00, (byte) 0xC0, (byte) 0xC1, (byte) 0x01, (byte) 0xC3, (byte) 0x03, (byte) 0x02, (byte) 0xC2, (byte) 0xC6, (byte) 0x06, (byte) 0x07, (byte) 0xC7, (byte) 0x05, (byte) 0xC5, (byte) 0xC4, (byte) 0x04, (byte) 0xCC, (byte) 0x0C, (byte) 0x0D, (byte) 0xCD, (byte) 0x0F, (byte) 0xCF, (byte) 0xCE, (byte) 0x0E, (byte) 0x0A, (byte) 0xCA, (byte) 0xCB, (byte) 0x0B, (byte) 0xC9, (byte) 0x09, (byte) 0x08, (byte) 0xC8, (byte) 0xD8, (byte) 0x18, (byte) 0x19, (byte) 0xD9, (byte) 0x1B, (byte) 0xDB, (byte) 0xDA, (byte) 0x1A, (byte) 0x1E, (byte) 0xDE, (byte) 0xDF, (byte) 0x1F, (byte) 0xDD, (byte) 0x1D, (byte) 0x1C, (byte) 0xDC, (byte) 0x14, (byte) 0xD4, (byte) 0xD5, (byte) 0x15, (byte) 0xD7, (byte) 0x17, (byte) 0x16, (byte) 0xD6, (byte) 0xD2, (byte) 0x12,            (byte) 0x13, (byte) 0xD3, (byte) 0x11, (byte) 0xD1, (byte) 0xD0, (byte) 0x10, (byte) 0xF0, (byte) 0x30, (byte) 0x31, (byte) 0xF1, (byte) 0x33, (byte) 0xF3, (byte) 0xF2, (byte) 0x32, (byte) 0x36, (byte) 0xF6, (byte) 0xF7, (byte) 0x37, (byte) 0xF5, (byte) 0x35, (byte) 0x34, (byte) 0xF4, (byte) 0x3C, (byte) 0xFC, (byte) 0xFD, (byte) 0x3D, (byte) 0xFF, (byte) 0x3F, (byte) 0x3E, (byte) 0xFE, (byte) 0xFA, (byte) 0x3A, (byte) 0x3B, (byte) 0xFB, (byte) 0x39, (byte) 0xF9, (byte) 0xF8, (byte) 0x38, (byte) 0x28, (byte) 0xE8, (byte) 0xE9, (byte) 0x29, (byte) 0xEB, (byte) 0x2B, (byte) 0x2A, (byte) 0xEA, (byte) 0xEE, (byte) 0x2E, (byte) 0x2F, (byte) 0xEF, (byte) 0x2D, (byte) 0xED, (byte) 0xEC, (byte) 0x2C, (byte) 0xE4, (byte) 0x24, (byte) 0x25, (byte) 0xE5, (byte) 0x27, (byte) 0xE7,            (byte) 0xE6, (byte) 0x26, (byte) 0x22, (byte) 0xE2, (byte) 0xE3, (byte) 0x23, (byte) 0xE1, (byte) 0x21, (byte) 0x20, (byte) 0xE0, (byte) 0xA0, (byte) 0x60, (byte) 0x61, (byte) 0xA1, (byte) 0x63, (byte) 0xA3, (byte) 0xA2, (byte) 0x62, (byte) 0x66, (byte) 0xA6, (byte) 0xA7, (byte) 0x67, (byte) 0xA5, (byte) 0x65, (byte) 0x64, (byte) 0xA4, (byte) 0x6C, (byte) 0xAC, (byte) 0xAD, (byte) 0x6D, (byte) 0xAF, (byte) 0x6F, (byte) 0x6E, (byte) 0xAE, (byte) 0xAA, (byte) 0x6A, (byte) 0x6B, (byte) 0xAB, (byte) 0x69, (byte) 0xA9, (byte) 0xA8, (byte) 0x68, (byte) 0x78, (byte) 0xB8, (byte) 0xB9, (byte) 0x79, (byte) 0xBB, (byte) 0x7B, (byte) 0x7A, (byte) 0xBA, (byte) 0xBE, (byte) 0x7E, (byte) 0x7F, (byte) 0xBF, (byte) 0x7D, (byte) 0xBD, (byte) 0xBC, (byte) 0x7C, (byte) 0xB4, (byte) 0x74,            (byte) 0x75, (byte) 0xB5, (byte) 0x77, (byte) 0xB7, (byte) 0xB6, (byte) 0x76, (byte) 0x72, (byte) 0xB2, (byte) 0xB3, (byte) 0x73, (byte) 0xB1, (byte) 0x71, (byte) 0x70, (byte) 0xB0, (byte) 0x50, (byte) 0x90, (byte) 0x91, (byte) 0x51, (byte) 0x93, (byte) 0x53, (byte) 0x52, (byte) 0x92, (byte) 0x96, (byte) 0x56, (byte) 0x57, (byte) 0x97, (byte) 0x55, (byte) 0x95, (byte) 0x94, (byte) 0x54, (byte) 0x9C, (byte) 0x5C, (byte) 0x5D, (byte) 0x9D, (byte) 0x5F, (byte) 0x9F, (byte) 0x9E, (byte) 0x5E, (byte) 0x5A, (byte) 0x9A, (byte) 0x9B, (byte) 0x5B, (byte) 0x99, (byte) 0x59, (byte) 0x58, (byte) 0x98, (byte) 0x88, (byte) 0x48, (byte) 0x49, (byte) 0x89, (byte) 0x4B, (byte) 0x8B, (byte) 0x8A, (byte) 0x4A, (byte) 0x4E, (byte) 0x8E, (byte) 0x8F, (byte) 0x4F, (byte) 0x8D, (byte) 0x4D,            (byte) 0x4C, (byte) 0x8C, (byte) 0x44, (byte) 0x84, (byte) 0x85, (byte) 0x45, (byte) 0x87, (byte) 0x47, (byte) 0x46, (byte) 0x86, (byte) 0x82, (byte) 0x42, (byte) 0x43, (byte) 0x83, (byte) 0x41, (byte) 0x81, (byte) 0x80, (byte) 0x40 };    /**     * 计算CRC16校验     *     * @param data     *            需要计算的数组     * @return CRC16校验值     */    public static int calcCrc16(byte[] data) {        return calcCrc16(data, 0, data.length);    }    /**     * 计算CRC16校验     *     * @param data     *            需要计算的数组     * @param offset     *            起始位置     * @param len     *            长度     * @return CRC16校验值     */    public static int calcCrc16(byte[] data, int offset, int len) {        return calcCrc16(data, offset, len, 0xffff);    }    /**     * 计算CRC16校验     *     * @param data     *            需要计算的数组     * @param offset     *            起始位置     * @param len     *            长度     * @param preval     *            之前的校验值     * @return CRC16校验值     */    public static int calcCrc16(byte[] data, int offset, int len, int preval) {        int ucCRCHi = (preval & 0xff00) >> 8;        int ucCRCLo = preval & 0x00ff;        int iIndex;        for (int i = 0; i < len; ++i) {            iIndex = (ucCRCLo ^ data[offset + i]) & 0x00ff;            ucCRCLo = ucCRCHi ^ crc16_tab_h[iIndex];            ucCRCHi = crc16_tab_l[iIndex];        }        return ((ucCRCHi & 0x00ff) << 8) | (ucCRCLo & 0x00ff) & 0xffff;    }}
原创粉丝点击