crc16 modbus校验

package com.pjmike.netty.server;

/**
 * @Description TODO
 * @Date 2019/10/14 18:09
 * @Author zsj
 */
public class CRC16MUtil {


    /**
     * 计算CRC16校验码
     *
     * @param bytes 字节数组
     * @return {@link String} 校验码
     * @since 1.0
     */
    public static byte[] getCRC(byte[] bytes) {
        int CRC = 0x0000ffff;
        int POLYNOMIAL = 0x0000a001;
        int i, j;
        for (i = 0; i < bytes.length; i++) {
            CRC ^= ((int) bytes[i] & 0x000000ff);
            for (j = 0; j < 8; j++) {
                if ((CRC & 0x00000001) != 0) {
                    CRC >>= 1;
                    CRC ^= POLYNOMIAL;
                } else {
                    CRC >>= 1;
                }
            }
        }
//        低字节在前,高字节在后
        CRC = ((CRC & 0x0000FF00) >> 8) | ((CRC & 0x000000FF) << 8);
        String crcStr = Integer.toHexString(CRC);
//        System.out.println(crcStr);
        byte[] result = hexString2Bytes(crcStr);
        return result;
    }

    /**
     * 将两个ASCII字符合成一个字节; 如:"EF"–> 0xEF
     *
     * @param src0 byte
     * @param src1 byte
     * @return byte
     */
    public static byte uniteBytes(byte src0, byte src1) {
        byte _b0 = Byte.decode("0x" + new String(new byte[]{src0})).byteValue();
        _b0 = (byte) (_b0 << 4);
        byte _b1 = Byte.decode("0x" + new String(new byte[]{src1})).byteValue();
        byte ret = (byte) (_b0 ^ _b1);
        return ret;
    }

    /**
     * 将指定字符串src,以每两个字符分割转换为16进制形式
     * 如:"2B44EFD9" –> byte[]{0x2B, 0x44, 0xEF,0xD9}
     *
     * @param src String
     * @return byte[]
     */
    public static byte[] hexString2Bytes(String src) {
        if (null == src || 0 == src.length()) {
            return null;
        }
        byte[] ret = new byte[src.length() / 2];
        byte[] tmp = src.getBytes();
        for (int i = 0; i < (tmp.length / 2); i++) {
            ret[i] = uniteBytes(tmp[i * 2], tmp[i * 2 + 1]);
        }
        return ret;
    }

    //byte 数组转为16进制字符串 long 8字节  1字节占2位
    public static String bytesToHex(byte[] bytes) {
        StringBuilder buf = new StringBuilder(bytes.length * 2);
        for (byte b : bytes) { // 使用String的format方法进行转换
            buf.append(String.format("%02x", new Integer(b & 0xff)));
        }
        return buf.toString();
    }

    // long 转10进制byte数组
    public static byte[] longToByteArray(long a) {
        return new byte[]{
                (byte) ((a >> 56) & 0xFF),
                (byte) ((a >> 48) & 0xFF),
                (byte) ((a >> 40) & 0xFF),
                (byte) ((a >> 32) & 0xFF),
                (byte) ((a >> 24) & 0xFF),
                (byte) ((a >> 16) & 0xFF),
                (byte) ((a >> 8) & 0xFF),
                (byte) (a & 0xFF)};
    }


    public static void main(String[] args) {

        final byte[] data = {
                0x19, 0x11, 0x05, 0x15, 0x16, 0x46, (byte) 0xA1, 0x5A, 0x5A, 0x5A, 0x5A
        };
        final byte[] res = CRC16MUtil.getCRC(data);
        Long l = 596L;
        byte[] lo = longToByteArray(l);
        System.out.println(bytesToHex(lo));
        System.out.println(11);
            

    }

}

你可能感兴趣的:(Java和Jvm)