校验方式详解
校验方式 |
多项式 |
初始值 |
前/后 |
异或值 |
CRC16_CCITT |
x16+x12+x5+1(0x1021) |
0x0000 |
低/高 |
0x0000 |
CRC16_CCITT_FALSE |
x16+x12+x5+1(0x1021) |
0xFFFF |
高/低 |
0x0000 |
CRC16_XMODEM |
x16+x12+x5+1(0x1021) |
0x0000 |
高/低 |
0x0000 |
CRC16_X25 |
x16+x12+x5+1(0x1021) |
0xFFFF |
低/高 |
0xFFFF |
CRC16_MODBUS |
x16+x15+x2+1(0x8005) |
0xFFFF |
低/高 |
0x0000 |
CRC16_IBM |
x16+x15+x2+1(0x8005) |
0x0000 |
低/高 |
0x0000 |
CRC16_MAXIM |
x16+x15+x2+1(0x8005) |
0x0000 |
低/高 |
0xFFFF |
CRC16_USB |
x16+x15+x2+1(0x8005) |
0xFFFF |
低/高 |
0xFFFF |
CRC16_DNP |
x16+x13+x12+x11+x10+x8+x6+x5+x2+1(0x3D65) |
0x0000 |
低/高 |
0xFFFF |
校验原理和步骤
- 预置1个16位的寄存器为十六进制FFFF(即全为1),称此寄存器为CRC寄存器;
- 把第一个8位二进制数据(既通讯信息帧的第一个字节)与16位的CRC寄存器的低8位相异或,把结果放于CRC寄存器,高八位数据不变;
- 把CRC寄存器的内容右移一位(朝低位)用0填补最高位,并检查右移后的移出位;
- 如果移出位为0:重复第3步(再次右移一位);如果移出位为1,CRC寄存器与多项式A001(1010 0000 0000 0001)进行异或;
- 重复步骤3和4,直到右移8次,这样整个8位数据全部进行了处理;
- 重复步骤2到步骤5,进行通讯信息帧下一个字节的处理;
- 将该通讯信息帧所有字节按上述步骤计算完成后,得到的16位CRC寄存器的高、低字节进行交换;
- 最后得到的CRC寄存器内容即为:CRC码。
- 以上计算步骤中的多项式 0xA001 是 0x8005 按位颠倒后的结果。
- 0x8408 是 0x1021 按位颠倒后的结果。
Java 实现
1/**
2 * Author:boxla
3 * Time:2019/09/11 16:09
4 */
5public class CRC16 {
6
7 /**
8 * @param buffer
9 * @return
10 */
11 public static int CRC16_CCITT(byte[] buffer) {
12 int wCRCin = 0x0000;
13 int wCPoly = 0x8408;
14 for (byte b : buffer) {
15 wCRCin ^= ((int) b & 0x00ff);
16 for (int j = 0; j < 8; j++) {
17 if ((wCRCin & 0x0001) != 0) {
18 wCRCin >>= 1;
19 wCRCin ^= wCPoly;
20 } else {
21 wCRCin >>= 1;
22 }
23 }
24 }
25 return wCRCin ^= 0x0000;
26
27 }
28
29 /**
30 * @param buffer
31 * @return
32 */
33 public static int CRC16_CCITT_FALSE(byte[] buffer) {
34 int wCRCin = 0xffff;
35 int wCPoly = 0x1021;
36 for (byte b : buffer) {
37 for (int i = 0; i < 8; i++) {
38 boolean bit = ((b >> (7 - i) & 1) == 1);
39 boolean c15 = ((wCRCin >> 15 & 1) == 1);
40 wCRCin <<= 1;
41 if (c15 ^ bit)
42 wCRCin ^= wCPoly;
43 }
44 }
45 wCRCin &= 0xffff;
46 return wCRCin ^= 0x0000;
47 }
48
49 /**
50 * @param buffer
51 * @return
52 */
53 public static int CRC16_XMODEM(byte[] buffer) {
54 int wCRCin = 0x0000;
55 int wCPoly = 0x1021;
56 for (byte b : buffer) {
57 for (int i = 0; i < 8; i++) {
58 boolean bit = ((b >> (7 - i) & 1) == 1);
59 boolean c15 = ((wCRCin >> 15 & 1) == 1);
60 wCRCin <<= 1;
61 if (c15 ^ bit)
62 wCRCin ^= wCPoly;
63 }
64 }
65 wCRCin &= 0xffff;
66 return wCRCin ^= 0x0000;
67 }
68
69
70 /**
71 * @param buffer
72 * @return
73 */
74 public static int CRC16_X25(byte[] buffer) {
75 int wCRCin = 0xffff;
76 int wCPoly = 0x8408;
77 for (byte b : buffer) {
78 wCRCin ^= ((int) b & 0x00ff);
79 for (int j = 0; j < 8; j++) {
80 if ((wCRCin & 0x0001) != 0) {
81 wCRCin >>= 1;
82 wCRCin ^= wCPoly;
83 } else {
84 wCRCin >>= 1;
85 }
86 }
87 }
88 return wCRCin ^= 0xffff;
89 }
90
91 /**
92 * @param buffer
93 * @return
94 */
95 public static int CRC16_MODBUS(byte[] buffer) {
96 int wCRCin = 0xffff;
97 int POLYNOMIAL = 0xa001;
98 for (byte b : buffer) {
99 wCRCin ^= ((int) b & 0x00ff);
100 for (int j = 0; j < 8; j++) {
101 if ((wCRCin & 0x0001) != 0) {
102 wCRCin >>= 1;
103 wCRCin ^= POLYNOMIAL;
104 } else {
105 wCRCin >>= 1;
106 }
107 }
108 }
109 return wCRCin ^= 0x0000;
110 }
111
112 /**
113 * @param buffer
114 * @return
115 */
116 public static int CRC16_IBM(byte[] buffer) {
117 int wCRCin = 0x0000;
118 int wCPoly = 0xa001;
119 for (byte b : buffer) {
120 wCRCin ^= ((int) b & 0x00ff);
121 for (int j = 0; j < 8; j++) {
122 if ((wCRCin & 0x0001) != 0) {
123 wCRCin >>= 1;
124 wCRCin ^= wCPoly;
125 } else {
126 wCRCin >>= 1;
127 }
128 }
129 }
130 return wCRCin ^= 0x0000;
131 }
132
133 /**
134 * @param buffer
135 * @return
136 */
137 public static int CRC16_MAXIM(byte[] buffer) {
138 int wCRCin = 0x0000;
139 int wCPoly = 0xa001;
140 for (byte b : buffer) {
141 wCRCin ^= ((int) b & 0x00ff);
142 for (int j = 0; j < 8; j++) {
143 if ((wCRCin & 0x0001) != 0) {
144 wCRCin >>= 1;
145 wCRCin ^= wCPoly;
146 } else {
147 wCRCin >>= 1;
148 }
149 }
150 }
151 return wCRCin ^= 0xffff;
152 }
153
154 /**
155 * @param buffer
156 * @return
157 */
158 public static int CRC16_USB(byte[] buffer) {
159 int wCRCin = 0xFFFF;
160 int wCPoly = 0xa001;
161 for (byte b : buffer) {
162 wCRCin ^= ((int) b & 0x00ff);
163 for (int j = 0; j < 8; j++) {
164 if ((wCRCin & 0x0001) != 0) {
165 wCRCin >>= 1;
166 wCRCin ^= wCPoly;
167 } else {
168 wCRCin >>= 1;
169 }
170 }
171 }
172 return wCRCin ^= 0xffff;
173 }
174
175 /**
176 * @param buffer
177 * @return
178 */
179 public static int CRC16_DNP(byte[] buffer) {
180 int wCRCin = 0x0000;
181 int wCPoly = 0xA6BC;
182 for (byte b : buffer) {
183 wCRCin ^= ((int) b & 0x00ff);
184 for (int j = 0; j < 8; j++) {
185 if ((wCRCin & 0x0001) != 0) {
186 wCRCin >>= 1;
187 wCRCin ^= wCPoly;
188 } else {
189 wCRCin >>= 1;
190 }
191 }
192 }
193 return wCRCin ^= 0xffff;
194 }
195}
相关资料
在线 CRC 校验工具