leutu
2024-06-03 3ef35e6cd16bbfa206b26bb3271eac40ad020bcb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package com.fastbee.common.utils.gateway;
 
 
import com.fastbee.common.utils.gateway.protocol.ByteUtils;
 
public class CRC16Utils {
 
    //ff
    private static int CRC_FF = 0x000000ff;
    //01
    private static int CRC_01 = 0x00000001;
    //04
    private static final int LENGTH_04 = 4;
    //16进制
    private static final int OXFF = 0xff;
 
    /**
     * 低位在前,高位在后
     *
     * @param bytes
     * @return
     */
    public static String getCRC(byte[] bytes) {
        return getCRC(bytes, true);
    }
 
    /**
     * @param bytes
     * @param lb    是否低位在前, 高位在后
     * @return
     */
    public static String getCRC(byte[] bytes, boolean lb) {
        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;
                }
            }
        }
 
        //结果转换为16进制
        String result = Integer.toHexString(CRC).toUpperCase();
        if (result.length() != 4) {
            StringBuffer sb = new StringBuffer("0000");
            result = sb.replace(4 - result.length(), 4, result).toString();
        }
 
        if (lb) { // 低位在前, 高位在后
            result = result.substring(2, 4) + result.substring(0, 2);
        }
 
        return result;
    }
 
    /**
     * 计算CRC校验和
     *
     * @param bytes
     * @return 返回 byte[]
     */
    public static byte[] getCrc16Byte(byte[] bytes) {
 
        //寄存器全为1
        int CRC_16 = 0x0000ffff;
        // 多项式校验值
        int POLYNOMIAL = 0x0000a001;
        for (byte aByte : bytes) {
            CRC_16 ^= ((int) aByte & CRC_FF);
            for (int j = 0; j < 8; j++) {
                if ((CRC_16 & CRC_01) != 0) {
                    CRC_16 >>= 1;
                    CRC_16 ^= POLYNOMIAL;
                } else {
                    CRC_16 >>= 1;
                }
            }
        }
        //  低8位 ,高8位
        return new byte[]{(byte) (CRC_16 & OXFF), (byte) (CRC_16 >> 8 & OXFF)};
    }
 
    public static byte[] CRC(byte[] source) {
        source[2] = (byte) ((int) source[2] * 2);
        byte[] result = new byte[source.length + 2];
        byte[] crc16Byte = CRC16Utils.getCrc16Byte(source);
        System.arraycopy(source, 0, result, 0, source.length);
        System.arraycopy(crc16Byte, 0, result, result.length - 2, 2);
        return result;
    }
 
    public static byte CRC8(byte[] buffer) {
        int crci = 0xFF; //起始字节FF
        for (int j = 0; j < buffer.length; j++) {
            crci ^= buffer[j] & 0xFF;
            for (int i = 0; i < 8; i++) {
                if ((crci & 1) != 0) {
                    crci >>= 1;
                    crci ^= 0xB8; //多项式当中的那个啥的,不同多项式不一样
                } else {
                    crci >>= 1;
                }
            }
        }
        return (byte) crci;
    }
 
 
    public static void main(String[] args)throws Exception {
        String hex = "01000002";
        byte[] bytes = ByteUtils.hexToByte(hex);
        String crc = getCRC(bytes);
        System.out.println(crc);
        String crc8 = "680868333701120008C100";
        byte[] byte8 = ByteUtils.hexToByte(crc8);
        int b = CRC8(byte8);
        System.out.println((int) b);
    }
 
 
}