liurunyu
2024-12-02 36268a2ea052f07ab28b9f1d4d6a654bf4fbbd13
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package com.dy.common.util;
 
 
@SuppressWarnings("unused")
public final class CRC16 {
    
    /*
     * 16位的CRC值是无符号两字节整数,
     * @param b 字节数组
     * @return CRC
 
    public int CRC(byte[] b) {
        int crc = 0xFFFF;
        int len = b.length;
        for (int j = 0 ; j < len; j++) {
            crc = crc ^ ((b[j] + 256) % 256) ;//转换成无符号数,因为终端实现(C语言或汇编语言)都用的是无符号数
            for (int i = 0; i < 8; i++) {
                if ((crc & 0x0001) == 0x0001) {
                    crc = (crc >> 1) ^ 0xA001;
                } else {
                    crc = crc >> 1;
                }
            }
        }
        return crc;
    }
    */
 
    /**
     * 16位的CRC值是无符号两字节整数,
     * @param b 字节数组
     * @param startIndex 开始下标
     * @param endIndex 截止下标
     * @return CRC
     */
    @SuppressWarnings("unused")
    public short CRC(byte[] b, int startIndex, int endIndex) {
        int crc = 0xFFFF;
        for (int j = startIndex ; j <= endIndex; j++) {
            crc = crc ^ ((b[j] + 256) % 256) ;//转换成无符号数,因为终端实现(C语言或汇编语言)都用的是无符号数
            for (int i = 0; i < 8; i++) {
                if ((crc & 0x0001) == 0x0001) {
                    crc = (crc >> 1) ^ 0xA001;
                } else {
                    crc = crc >> 1;
                }
            }
        }
        return (short)crc;
    }
 
 
    private static final int[] crc16_rev_table = new int[]{
        0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
        0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
        0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
        0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
        0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
        0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
        0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
        0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
        0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
        0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
        0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
        0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
        0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
        0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
        0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
        0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
        0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
        0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
        0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
        0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
        0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
        0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
        0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
        0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
        0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
        0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
        0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
        0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
        0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
        0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
        0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
        0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
    };
 
    /**
     * 16位的CRC值是无符号两字节整数,
     * @param bs 字节数组
     * @param startIndex 开始下标
     * @param endIndex 截止下标
     * @return CRC
     */
    @SuppressWarnings("unused")
    public short CRC16_table(byte[] bs, int startIndex, int endIndex) {
        short x ;
        short crc = (short)0xffff;
        if(bs != null && bs.length >= endIndex + 1){
            for (int i = startIndex ; i <= endIndex; i++){
                x = (short)(crc ^ bs[i]) ;
                crc = (short)((crc >> 8) ^ crc16_rev_table[x & 0x00FF]) ;
            }
        }
        return crc ;
    }
    /**
     * 16位的CRC值 ,查表法
     * @param bs 字节数组
     * @return CRC
     */
    public short CRC16_table(byte[] bs) {
        short x ;
        short crc = (short)0xffff;
        if(bs != null && bs.length > 0){
            for(byte b : bs){
                x = (short)(crc ^ b) ;
                crc = (short)((crc >> 8) ^ crc16_rev_table[x & 0x00FF]) ;
            }
        }
        return crc ;
    }
 
 
    /**
     * 数据高位在低字节(数组下标小),数据低位在高字节(数组下标大),
     * 例如258这个数,放进四个字节数组b中:
     * b[0](低字节)=0,
     * b[1](次低字节)=0,
     * b[2](次高字节)=1(数据高位),
     * b[3](高字节)=2(数据低位),
     * @param c 整数
     * @return 转成的数组
     */
    public byte[] CRC2bytes(int c) {
        byte[] crc = new byte[2];
        System.arraycopy(new byte[] {(byte)(c / 256) }, 0, crc, 0, 1);
        System.arraycopy(new byte[] {(byte)(c - ((c / 256) * 256)) }, 0, crc, 1, 1);
        return crc;
    }
    
 
}