张世豪
5 小时以前 d22349714c8d199c02f336f90fba841ef8f5cd39
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
package publicway;
/**
 * Modbus CRC16 ¹¤¾ßÀà
 * <p>
 * Ìṩ¾²Ì¬·½·¨ calculate(String hexString) ½ÓÊÕÒ»¸ö²»´ø¿Õ¸ñµÄÊ®Áù½øÖÆ×Ö·û´®£¬
 * ·µ»Ø 4 Î»µÄÊ®Áù½øÖÆ CRC Ð£ÑéÂ루Сд£¬²»´ø 0x Ç°×º£©£¬Ó빤³ÌÖРHexUtil.calculate ±£³ÖÒ»Ö¡£
 */
public class CRC16Modbus {
 
    /**
     * ¼ÆËã Modbus CRC16£¨¶àÏîʽ 0xA001£¬³õʼֵ 0xFFFF£©¡£
     *
     * @param hexString ÊäÈëµÄÊ®Áù½øÖÆ×Ö·û´®£¬ÀýÈç "DDCC000EF0..."£¨´óСд¾ù¿É£¬ÔÊÐí°üº¬¿Õ¸ñ£©
     * @return 4 Î»Ê®Áù½øÖÆ×Ö·û´®£¨Ð¡Ð´£©£¬ÀýÈç "f1a3"¡£Èç¹ûÊäÈëΪ¿Õ·µ»Ø "0000"¡£
     */
    public static String calculate(String hexString) {
        if (hexString == null || hexString.trim().length() == 0) {
            return "0000";
        }
 
        byte[] data = hexStringToBytes(hexString);
        int crc = 0xFFFF;
        for (byte b : data) {
            crc ^= b & 0xFF;
            for (int i = 0; i < 8; i++) {
                if ((crc & 1) == 1) {
                    crc = (crc >>> 1) ^ 0xA001;
                } else {
                    crc = crc >>> 1;
                }
            }
        }
        String result = String.format("%4s", Integer.toHexString(crc)).replace(' ', '0');
        return result.toUpperCase();
    }
 
    // ¼òµ¥µÄ hex -> byte[] ×ª»»£¬Ö§³Ö´ø»ò²»´ø¿Õ¸ñµÄ×Ö·û´®£¬³¤¶ÈÎªÆæÊýʱÔÚǰ²¹ 0
    private static byte[] hexStringToBytes(String hex) {
        String s = hex.replaceAll("\\s+", "");
        if (s.length() % 2 != 0) {
            s = "0" + s;
        }
        int len = s.length() / 2;
        byte[] data = new byte[len];
        for (int i = 0; i < len; i++) {
            int pos = i * 2;
            data[i] = (byte) Integer.parseInt(s.substring(pos, pos + 2), 16);
        }
        return data;
    }
    
    public static void main(String args[]) {
        System.out.println(calculate("DD CC 00 08 F0 01 51 5A A5 5A A5 11"));
    }
 
}