2222import java .util .zip .Checksum ;
2323
2424/**
25- * CRC-16 checksum implementations you can customize with a table and input value.
25+ * CRC-16 checksum implementations you can customize with a table and init value.
2626 * <p>
2727 * Since there are so many CRC-16 variants, we do not pick a default.
2828 * </p>
2929 * <p>
30- * To create a create a custom variant of CRC16-MODBUS with a init value of {@code 0x0000}, call :
30+ * For example, to create a create a custom variant of CRC16-MODBUS with an init value of {@code 0x0000}, use :
3131 * </p>
3232 * <pre>
3333 * Checksum crc16 = CRC16.builder()
@@ -49,7 +49,7 @@ public class CRC16 implements Checksum {
4949 */
5050 public static class Builder implements Supplier <CRC16 > {
5151
52- private int init = INIT_DEFAULT ;
52+ private int init ;
5353 private int [] table ;
5454
5555 /**
@@ -100,9 +100,8 @@ private Builder table(final int[] table) {
100100 }
101101 }
102102
103- private static final int INIT_DEFAULT = 0x0000 ;
104103 // @formatter:off
105- private static final int [] T_MODBUS = {
104+ private static final int [] ARC = {
106105 0x0000 , 0xC0C1 , 0xC181 , 0x0140 , 0xC301 , 0x03C0 , 0x0280 , 0xC241 ,
107106 0xC601 , 0x06C0 , 0x0780 , 0xC741 , 0x0500 , 0xC5C1 , 0xC481 , 0x0440 ,
108107 0xCC01 , 0x0CC0 , 0x0D80 , 0xCD41 , 0x0F00 , 0xCFC1 , 0xCE81 , 0x0E40 ,
@@ -137,8 +136,49 @@ private Builder table(final int[] table) {
137136 0x8201 , 0x42C0 , 0x4380 , 0x8341 , 0x4100 , 0x81C1 , 0x8081 , 0x4040
138137 };
139138 // @formatter:on
139+ private static final int ARC_INIT = 0x0000 ;
140+
141+ // @formatter:off
142+ private static final int [] CCITT = {
143+ 0x0000 , 0x1189 , 0x2312 , 0x329B , 0x4624 , 0x57AD , 0x6536 , 0x74BF ,
144+ 0x8C48 , 0x9DC1 , 0xAF5A , 0xBED3 , 0xCA6C , 0xDBE5 , 0xE97E , 0xF8F7 ,
145+ 0x1081 , 0x0108 , 0x3393 , 0x221A , 0x56A5 , 0x472C , 0x75B7 , 0x643E ,
146+ 0x9CC9 , 0x8D40 , 0xBFDB , 0xAE52 , 0xDAED , 0xCB64 , 0xF9FF , 0xE876 ,
147+ 0x2102 , 0x308B , 0x0210 , 0x1399 , 0x6726 , 0x76AF , 0x4434 , 0x55BD ,
148+ 0xAD4A , 0xBCC3 , 0x8E58 , 0x9FD1 , 0xEB6E , 0xFAE7 , 0xC87C , 0xD9F5 ,
149+ 0x3183 , 0x200A , 0x1291 , 0x0318 , 0x77A7 , 0x662E , 0x54B5 , 0x453C ,
150+ 0xBDCB , 0xAC42 , 0x9ED9 , 0x8F50 , 0xFBEF , 0xEA66 , 0xD8FD , 0xC974 ,
151+ 0x4204 , 0x538D , 0x6116 , 0x709F , 0x0420 , 0x15A9 , 0x2732 , 0x36BB ,
152+ 0xCE4C , 0xDFC5 , 0xED5E , 0xFCD7 , 0x8868 , 0x99E1 , 0xAB7A , 0xBAF3 ,
153+ 0x5285 , 0x430C , 0x7197 , 0x601E , 0x14A1 , 0x0528 , 0x37B3 , 0x263A ,
154+ 0xDECD , 0xCF44 , 0xFDDF , 0xEC56 , 0x98E9 , 0x8960 , 0xBBFB , 0xAA72 ,
155+ 0x6306 , 0x728F , 0x4014 , 0x519D , 0x2522 , 0x34AB , 0x0630 , 0x17B9 ,
156+ 0xEF4E , 0xFEC7 , 0xCC5C , 0xDDD5 , 0xA96A , 0xB8E3 , 0x8A78 , 0x9BF1 ,
157+ 0x7387 , 0x620E , 0x5095 , 0x411C , 0x35A3 , 0x242A , 0x16B1 , 0x0738 ,
158+ 0xFFCF , 0xEE46 , 0xDCDD , 0xCD54 , 0xB9EB , 0xA862 , 0x9AF9 , 0x8B70 ,
159+ 0x8408 , 0x9581 , 0xA71A , 0xB693 , 0xC22C , 0xD3A5 , 0xE13E , 0xF0B7 ,
160+ 0x0840 , 0x19C9 , 0x2B52 , 0x3ADB , 0x4E64 , 0x5FED , 0x6D76 , 0x7CFF ,
161+ 0x9489 , 0x8500 , 0xB79B , 0xA612 , 0xD2AD , 0xC324 , 0xF1BF , 0xE036 ,
162+ 0x18C1 , 0x0948 , 0x3BD3 , 0x2A5A , 0x5EE5 , 0x4F6C , 0x7DF7 , 0x6C7E ,
163+ 0xA50A , 0xB483 , 0x8618 , 0x9791 , 0xE32E , 0xF2A7 , 0xC03C , 0xD1B5 ,
164+ 0x2942 , 0x38CB , 0x0A50 , 0x1BD9 , 0x6F66 , 0x7EEF , 0x4C74 , 0x5DFD ,
165+ 0xB58B , 0xA402 , 0x9699 , 0x8710 , 0xF3AF , 0xE226 , 0xD0BD , 0xC134 ,
166+ 0x39C3 , 0x284A , 0x1AD1 , 0x0B58 , 0x7FE7 , 0x6E6E , 0x5CF5 , 0x4D7C ,
167+ 0xC60C , 0xD785 , 0xE51E , 0xF497 , 0x8028 , 0x91A1 , 0xA33A , 0xB2B3 ,
168+ 0x4A44 , 0x5BCD , 0x6956 , 0x78DF , 0x0C60 , 0x1DE9 , 0x2F72 , 0x3EFB ,
169+ 0xD68D , 0xC704 , 0xF59F , 0xE416 , 0x90A9 , 0x8120 , 0xB3BB , 0xA232 ,
170+ 0x5AC5 , 0x4B4C , 0x79D7 , 0x685E , 0x1CE1 , 0x0D68 , 0x3FF3 , 0x2E7A ,
171+ 0xE70E , 0xF687 , 0xC41C , 0xD595 , 0xA12A , 0xB0A3 , 0x8238 , 0x93B1 ,
172+ 0x6B46 , 0x7ACF , 0x4854 , 0x59DD , 0x2D62 , 0x3CEB , 0x0E70 , 0x1FF9 ,
173+ 0xF78F , 0xE606 , 0xD49D , 0xC514 , 0xB1AB , 0xA022 , 0x92B9 , 0x8330 ,
174+ 0x7BC7 , 0x6A4E , 0x58D5 , 0x495C , 0x3DE3 , 0x2C6A , 0x1EF1 , 0x0F78
175+ };
176+ // @formatter:on
177+
178+ private static final int CCITT_INIT = 0x0000 ;
179+
140180 // @formatter:off
141- private static final int [] T_CCITT = {
181+ private static final int [] MCRF4XX = {
142182 0x0000 , 0x1189 , 0x2312 , 0x329B , 0x4624 , 0x57AD , 0x6536 , 0x74BF ,
143183 0x8C48 , 0x9DC1 , 0xAF5A , 0xBED3 , 0xCA6C , 0xDBE5 , 0xE97E , 0xF8F7 ,
144184 0x1081 , 0x0108 , 0x3393 , 0x221A , 0x56A5 , 0x472C , 0x75B7 , 0x643E ,
@@ -174,6 +214,107 @@ private Builder table(final int[] table) {
174214 };
175215 // @formatter:on
176216
217+ private static final int MCRF4XX_INIT = 0xFFFF ;
218+
219+ // @formatter:off
220+ private static final int [] MODBUS = {
221+ 0x0000 , 0xC0C1 , 0xC181 , 0x0140 , 0xC301 , 0x03C0 , 0x0280 , 0xC241 ,
222+ 0xC601 , 0x06C0 , 0x0780 , 0xC741 , 0x0500 , 0xC5C1 , 0xC481 , 0x0440 ,
223+ 0xCC01 , 0x0CC0 , 0x0D80 , 0xCD41 , 0x0F00 , 0xCFC1 , 0xCE81 , 0x0E40 ,
224+ 0x0A00 , 0xCAC1 , 0xCB81 , 0x0B40 , 0xC901 , 0x09C0 , 0x0880 , 0xC841 ,
225+ 0xD801 , 0x18C0 , 0x1980 , 0xD941 , 0x1B00 , 0xDBC1 , 0xDA81 , 0x1A40 ,
226+ 0x1E00 , 0xDEC1 , 0xDF81 , 0x1F40 , 0xDD01 , 0x1DC0 , 0x1C80 , 0xDC41 ,
227+ 0x1400 , 0xD4C1 , 0xD581 , 0x1540 , 0xD701 , 0x17C0 , 0x1680 , 0xD641 ,
228+ 0xD201 , 0x12C0 , 0x1380 , 0xD341 , 0x1100 , 0xD1C1 , 0xD081 , 0x1040 ,
229+ 0xF001 , 0x30C0 , 0x3180 , 0xF141 , 0x3300 , 0xF3C1 , 0xF281 , 0x3240 ,
230+ 0x3600 , 0xF6C1 , 0xF781 , 0x3740 , 0xF501 , 0x35C0 , 0x3480 , 0xF441 ,
231+ 0x3C00 , 0xFCC1 , 0xFD81 , 0x3D40 , 0xFF01 , 0x3FC0 , 0x3E80 , 0xFE41 ,
232+ 0xFA01 , 0x3AC0 , 0x3B80 , 0xFB41 , 0x3900 , 0xF9C1 , 0xF881 , 0x3840 ,
233+ 0x2800 , 0xE8C1 , 0xE981 , 0x2940 , 0xEB01 , 0x2BC0 , 0x2A80 , 0xEA41 ,
234+ 0xEE01 , 0x2EC0 , 0x2F80 , 0xEF41 , 0x2D00 , 0xEDC1 , 0xEC81 , 0x2C40 ,
235+ 0xE401 , 0x24C0 , 0x2580 , 0xE541 , 0x2700 , 0xE7C1 , 0xE681 , 0x2640 ,
236+ 0x2200 , 0xE2C1 , 0xE381 , 0x2340 , 0xE101 , 0x21C0 , 0x2080 , 0xE041 ,
237+ 0xA001 , 0x60C0 , 0x6180 , 0xA141 , 0x6300 , 0xA3C1 , 0xA281 , 0x6240 ,
238+ 0x6600 , 0xA6C1 , 0xA781 , 0x6740 , 0xA501 , 0x65C0 , 0x6480 , 0xA441 ,
239+ 0x6C00 , 0xACC1 , 0xAD81 , 0x6D40 , 0xAF01 , 0x6FC0 , 0x6E80 , 0xAE41 ,
240+ 0xAA01 , 0x6AC0 , 0x6B80 , 0xAB41 , 0x6900 , 0xA9C1 , 0xA881 , 0x6840 ,
241+ 0x7800 , 0xB8C1 , 0xB981 , 0x7940 , 0xBB01 , 0x7BC0 , 0x7A80 , 0xBA41 ,
242+ 0xBE01 , 0x7EC0 , 0x7F80 , 0xBF41 , 0x7D00 , 0xBDC1 , 0xBC81 , 0x7C40 ,
243+ 0xB401 , 0x74C0 , 0x7580 , 0xB541 , 0x7700 , 0xB7C1 , 0xB681 , 0x7640 ,
244+ 0x7200 , 0xB2C1 , 0xB381 , 0x7340 , 0xB101 , 0x71C0 , 0x7080 , 0xB041 ,
245+ 0x5000 , 0x90C1 , 0x9181 , 0x5140 , 0x9301 , 0x53C0 , 0x5280 , 0x9241 ,
246+ 0x9601 , 0x56C0 , 0x5780 , 0x9741 , 0x5500 , 0x95C1 , 0x9481 , 0x5440 ,
247+ 0x9C01 , 0x5CC0 , 0x5D80 , 0x9D41 , 0x5F00 , 0x9FC1 , 0x9E81 , 0x5E40 ,
248+ 0x5A00 , 0x9AC1 , 0x9B81 , 0x5B40 , 0x9901 , 0x59C0 , 0x5880 , 0x9841 ,
249+ 0x8801 , 0x48C0 , 0x4980 , 0x8941 , 0x4B00 , 0x8BC1 , 0x8A81 , 0x4A40 ,
250+ 0x4E00 , 0x8EC1 , 0x8F81 , 0x4F40 , 0x8D01 , 0x4DC0 , 0x4C80 , 0x8C41 ,
251+ 0x4400 , 0x84C1 , 0x8581 , 0x4540 , 0x8701 , 0x47C0 , 0x4680 , 0x8641 ,
252+ 0x8201 , 0x42C0 , 0x4380 , 0x8341 , 0x4100 , 0x81C1 , 0x8081 , 0x4040
253+ };
254+ // @formatter:on
255+
256+ private static final int MODBUS_INIT = 0xFFFF ;
257+
258+ private static final int [] NRSC5 = {
259+ 0x0000 , 0x35A4 , 0x6B48 , 0x5EEC , 0xD690 , 0xE334 , 0xBDD8 , 0x887C ,
260+ 0x0D01 , 0x38A5 , 0x6649 , 0x53ED , 0xDB91 , 0xEE35 , 0xB0D9 , 0x857D ,
261+ 0x1A02 , 0x2FA6 , 0x714A , 0x44EE , 0xCC92 , 0xF936 , 0xA7DA , 0x927E ,
262+ 0x1703 , 0x22A7 , 0x7C4B , 0x49EF , 0xC193 , 0xF437 , 0xAADB , 0x9F7F ,
263+ 0x3404 , 0x01A0 , 0x5F4C , 0x6AE8 , 0xE294 , 0xD730 , 0x89DC , 0xBC78 ,
264+ 0x3905 , 0x0CA1 , 0x524D , 0x67E9 , 0xEF95 , 0xDA31 , 0x84DD , 0xB179 ,
265+ 0x2E06 , 0x1BA2 , 0x454E , 0x70EA , 0xF896 , 0xCD32 , 0x93DE , 0xA67A ,
266+ 0x2307 , 0x16A3 , 0x484F , 0x7DEB , 0xF597 , 0xC033 , 0x9EDF , 0xAB7B ,
267+ 0x6808 , 0x5DAC , 0x0340 , 0x36E4 , 0xBE98 , 0x8B3C , 0xD5D0 , 0xE074 ,
268+ 0x6509 , 0x50AD , 0x0E41 , 0x3BE5 , 0xB399 , 0x863D , 0xD8D1 , 0xED75 ,
269+ 0x720A , 0x47AE , 0x1942 , 0x2CE6 , 0xA49A , 0x913E , 0xCFD2 , 0xFA76 ,
270+ 0x7F0B , 0x4AAF , 0x1443 , 0x21E7 , 0xA99B , 0x9C3F , 0xC2D3 , 0xF777 ,
271+ 0x5C0C , 0x69A8 , 0x3744 , 0x02E0 , 0x8A9C , 0xBF38 , 0xE1D4 , 0xD470 ,
272+ 0x510D , 0x64A9 , 0x3A45 , 0x0FE1 , 0x879D , 0xB239 , 0xECD5 , 0xD971 ,
273+ 0x460E , 0x73AA , 0x2D46 , 0x18E2 , 0x909E , 0xA53A , 0xFBD6 , 0xCE72 ,
274+ 0x4B0F , 0x7EAB , 0x2047 , 0x15E3 , 0x9D9F , 0xA83B , 0xF6D7 , 0xC373 ,
275+ 0xD010 , 0xE5B4 , 0xBB58 , 0x8EFC , 0x0680 , 0x3324 , 0x6DC8 , 0x586C ,
276+ 0xDD11 , 0xE8B5 , 0xB659 , 0x83FD , 0x0B81 , 0x3E25 , 0x60C9 , 0x556D ,
277+ 0xCA12 , 0xFFB6 , 0xA15A , 0x94FE , 0x1C82 , 0x2926 , 0x77CA , 0x426E ,
278+ 0xC713 , 0xF2B7 , 0xAC5B , 0x99FF , 0x1183 , 0x2427 , 0x7ACB , 0x4F6F ,
279+ 0xE414 , 0xD1B0 , 0x8F5C , 0xBAF8 , 0x3284 , 0x0720 , 0x59CC , 0x6C68 ,
280+ 0xE915 , 0xDCB1 , 0x825D , 0xB7F9 , 0x3F85 , 0x0A21 , 0x54CD , 0x6169 ,
281+ 0xFE16 , 0xCBB2 , 0x955E , 0xA0FA , 0x2886 , 0x1D22 , 0x43CE , 0x766A ,
282+ 0xF317 , 0xC6B3 , 0x985F , 0xADFB , 0x2587 , 0x1023 , 0x4ECF , 0x7B6B ,
283+ 0xB818 , 0x8DBC , 0xD350 , 0xE6F4 , 0x6E88 , 0x5B2C , 0x05C0 , 0x3064 ,
284+ 0xB519 , 0x80BD , 0xDE51 , 0xEBF5 , 0x6389 , 0x562D , 0x08C1 , 0x3D65 ,
285+ 0xA21A , 0x97BE , 0xC952 , 0xFCF6 , 0x748A , 0x412E , 0x1FC2 , 0x2A66 ,
286+ 0xAF1B , 0x9ABF , 0xC453 , 0xF1F7 , 0x798B , 0x4C2F , 0x12C3 , 0x2767 ,
287+ 0x8C1C , 0xB9B8 , 0xE754 , 0xD2F0 , 0x5A8C , 0x6F28 , 0x31C4 , 0x0460 ,
288+ 0x811D , 0xB4B9 , 0xEA55 , 0xDFF1 , 0x578D , 0x6229 , 0x3CC5 , 0x0961 ,
289+ 0x961E , 0xA3BA , 0xFD56 , 0xC8F2 , 0x408E , 0x752A , 0x2BC6 , 0x1E62 ,
290+ 0x9B1F , 0xAEBB , 0xF057 , 0xC5F3 , 0x4D8F , 0x782B , 0x26C7 , 0x1363
291+ };
292+ // @formatter:on
293+
294+ private static final int NRSC5_INIT = 0xFFFF ;
295+
296+ /**
297+ * Creates a new CRC16-CCITT Checksum.
298+ * <p>
299+ * The init value is {@code 0x0000}.
300+ * </p>
301+ * <p>
302+ * Also known as:
303+ * </p>
304+ * <ul>
305+ * <li>CRC-16/ARC</li>
306+ * <li>ARC</li>
307+ * <li>CRC-16</li>
308+ * <li>CRC-16/LHA</li>
309+ * <li>CRC-IBM</li>
310+ * </ul>
311+ *
312+ * @return a new CRC16-CCITT Checksum.
313+ */
314+ public static CRC16 arc () {
315+ return builder ().setInit (ARC_INIT ).table (ARC ).get ();
316+ }
317+
177318 /**
178319 * Creates a new builder.
179320 * <p>
@@ -187,48 +328,118 @@ public static Builder builder() {
187328 }
188329
189330 /**
190- * Creates a new CRC16-CCITT.
331+ * Creates a new CRC16-CCITT Checksum .
191332 * <p>
192333 * The init value is {@code 0x0000}.
193334 * </p>
335+ * <p>
336+ * Also known as:
337+ * </p>
338+ * <ul>
339+ * <li>CRC-16/KERMIT</li>
340+ * <li>CRC-16/BLUETOOTH</li>
341+ * <li>CRC-16/CCITT</li>
342+ * <li>CRC-16/CCITT-TRUE</li>
343+ * <li>CRC-16/V-41-LSB</li>
344+ * <li>CRC-CCITT</li>
345+ * <li>KERMIT</li>
346+ * </ul>
194347 *
195- * @return a new CRC16-CCITT.
348+ * @return a new CRC16-CCITT Checksum .
196349 */
197350 public static CRC16 ccitt () {
198- return builder ().setInit (0x0000 ).table (T_CCITT ).get ();
351+ return builder ().setInit (CCITT_INIT ).table (CCITT ).get ();
352+ }
353+
354+ /**
355+ * Gets a copy of the CRC16-CCITT table.
356+ *
357+ * @return a copy of the CCRC16-CITT table.
358+ */
359+ public static int [] getArcTable () {
360+ return ARC .clone ();
199361 }
200362
201363 /**
202- * Gets a copy of the CCITT table.
364+ * Gets a copy of the CRC16- CCITT table.
203365 *
204- * @return a copy of the CCITT table.
366+ * @return a copy of the CCRC16-CITT table.
205367 */
206368 public static int [] getCcittTable () {
207- return T_CCITT .clone ();
369+ return CCITT .clone ();
370+ }
371+
372+ /**
373+ * Gets a copy of the CRC16-MCRF4XX table.
374+ *
375+ * @return a copy of the CRC16-MCRF4XX table.
376+ */
377+ public static int [] getMcrf4xxTable () {
378+ return MCRF4XX .clone ();
208379 }
209380
210381 /**
211- * Gets a copy of the MODBUS table.
382+ * Gets a copy of the CRC16- MODBUS table.
212383 *
213- * @return a copy of the MODBUS table.
384+ * @return a copy of the CRC16- MODBUS table.
214385 */
215386 public static int [] getModbusTable () {
216- return T_MODBUS .clone ();
387+ return MODBUS .clone ();
388+ }
389+
390+ /**
391+ * Gets a copy of the CRC16-NRSC-5 table.
392+ *
393+ * @return a copy of the CRC16-NRSC-5 table.
394+ */
395+ public static int [] getNrsc5Table () {
396+ return NRSC5 .clone ();
397+ }
398+
399+ /**
400+ * Creates a new instance for CRC16-MCRF4XX Checksum.
401+ * <p>
402+ * The init value is {@code 0xFFFF}.
403+ * </p>
404+ *
405+ * @return a new CRC16-MCRF4XX Checksum.
406+ */
407+ public static CRC16 mcrf4xx () {
408+ return builder ().setInit (MCRF4XX_INIT ).table (MCRF4XX ).get ();
217409 }
218410
219411 /**
220- * Creates a new CRC16-MODBUS.
412+ * Creates a new instance for CRC16-MODBUS Checksum .
221413 * <p>
222414 * CRC-16 checksum implementation based on polynomial {@code x<sup>16</spu> + x^15 + x^2 + 1 (0x8005)}.
223415 * </p>
224416 * <p>
225417 * The init value is {@code 0xFFFF}.
226418 * </p>
419+ * <p>
420+ * Also known as:
421+ * </p>
422+ * <ul>
423+ * <li>CRC-16/MODBUST</li>
424+ * <li>MODBUST</li>
425+ * </ul>
227426 *
228- * @return a new CRC16-MODBUS.
427+ * @return a new CRC16-MODBUS Checksum .
229428 */
230429 public static CRC16 modbus () {
231- return builder ().setInit (0xFFFF ).table (T_MODBUS ).get ();
430+ return builder ().setInit (MODBUS_INIT ).table (MODBUS ).get ();
431+ }
432+
433+ /**
434+ * Creates a new instance for CRC16-NRSC-5 Checksum.
435+ * <p>
436+ * The init value is {@code 0xFFFF}.
437+ * </p>
438+ *
439+ * @return a new CRC16-NRSC-5 Checksum.
440+ */
441+ public static CRC16 nrsc5 () {
442+ return builder ().setInit (NRSC5_INIT ).table (NRSC5 ).get ();
232443 }
233444
234445 /**
@@ -266,10 +477,16 @@ public void reset() {
266477 crc = init ;
267478 }
268479
480+ @ Override
481+ public String toString () {
482+ return String .format ("CRC16 [init=0x%04X, crc=0x%04X]" , init , crc );
483+ }
484+
269485 @ Override
270486 public void update (final byte [] b , final int off , final int len ) {
271- for (int i = 0 ; i < len ; i ++) {
272- update (b [off + i ]);
487+ final int end = len + off ;
488+ for (int i = off ; i < end ; i ++) {
489+ update (b [i ]);
273490 }
274491 }
275492
0 commit comments