GCC Code Coverage Report


Directory: Utils/Hash/
File: libcrc/lib_crc.c
Date: 2026-09-03 21:18:39
Exec Total Coverage
Lines: 0 76 0.0%
Functions: 0 9 0.0%
Branches: 0 50 0.0%

Line Branch Exec Source
1 // clang-format off
2 #include "lib_crc.h"
3
4
5
6 /*******************************************************************\
7 * *
8 * Library : lib_crc *
9 * File : lib_crc.c *
10 * Author : Lammert Bies 1999-2008 *
11 * E-mail : info@lammertbies.nl *
12 * Language : ANSI C *
13 * *
14 * *
15 * Description *
16 * =========== *
17 * *
18 * The file lib_crc.c contains the private and public func- *
19 * tions used for the calculation of CRC-16, CRC-CCITT and *
20 * CRC-32 cyclic redundancy values. *
21 * *
22 * *
23 * Dependencies *
24 * ============ *
25 * *
26 * lib_crc.h CRC definitions and prototypes *
27 * *
28 * *
29 * Modification history *
30 * ==================== *
31 * *
32 * Date Version Comment *
33 * *
34 * 2008-04-20 1.16 Added CRC-CCITT calculation for Kermit *
35 * *
36 * 2007-04-01 1.15 Added CRC16 calculation for Modbus *
37 * *
38 * 2007-03-28 1.14 Added CRC16 routine for Sick devices *
39 * *
40 * 2005-12-17 1.13 Added CRC-CCITT with initial 0x1D0F *
41 * *
42 * 2005-05-14 1.12 Added CRC-CCITT with start value 0 *
43 * *
44 * 2005-02-05 1.11 Fixed bug in CRC-DNP routine *
45 * *
46 * 2005-02-04 1.10 Added CRC-DNP routines *
47 * *
48 * 1999-02-21 1.01 Added FALSE and TRUE mnemonics *
49 * *
50 * 1999-01-22 1.00 Initial source *
51 * *
52 \*******************************************************************/
53
54
55
56 /*******************************************************************\
57 * *
58 * #define P_xxxx *
59 * *
60 * The CRC's are computed using polynomials. The coefficients *
61 * for the algorithms are defined by the following constants. *
62 * *
63 \*******************************************************************/
64
65 #define P_16 (0xA001)
66 #define P_32 (0xEDB88320L)
67 #define P_CCITT (0x1021)
68 #define P_DNP (0xA6BC)
69 #define P_KERMIT (0x8408)
70 #define P_SICK (0x8005)
71
72
73
74 /*******************************************************************\
75 * *
76 * static int crc_tab...init *
77 * static unsigned ... crc_tab...[] *
78 * *
79 * The algorithms use tables with precalculated values. This *
80 * speeds up the calculation dramatically. The first time the *
81 * CRC function is called, the table for that specific calcu- *
82 * lation is set up. The ...init variables are used to deter- *
83 * mine if the initialization has taken place. The calculated *
84 * values are stored in the crc_tab... arrays. *
85 * *
86 * The variables are declared static. This makes them invisi- *
87 * ble for other modules of the program. *
88 * *
89 \*******************************************************************/
90
91 static int crc_tab16_init = CRC_FALSE;
92 // F PRIME CHANGE (see header)
93 #if 0
94 static int crc_tab32_init = CRC_FALSE;
95 #endif
96 static int crc_tabccitt_init = CRC_FALSE;
97 static int crc_tabdnp_init = CRC_FALSE;
98 static int crc_tabkermit_init = CRC_FALSE;
99
100 static unsigned short crc_tab16[256];
101 // F PRIME CHANGE (see header)
102 #if 0
103 static unsigned long crc_tab32[256];
104 #endif
105 static unsigned short crc_tabccitt[256];
106 static unsigned short crc_tabdnp[256];
107 static unsigned short crc_tabkermit[256];
108
109
110
111 /*******************************************************************\
112 * *
113 * static void init_crc...tab(); *
114 * *
115 * Three local functions are used to initialize the tables *
116 * with values for the algorithm. *
117 * *
118 \*******************************************************************/
119
120 static void init_crc16_tab( void );
121 // F PRIME CHANGE (see header)
122 #if 0
123 static void init_crc32_tab( void );
124 #endif
125 static void init_crcccitt_tab( void );
126 static void init_crcdnp_tab( void );
127 static void init_crckermit_tab( void );
128
129
130
131 /*******************************************************************\
132 * *
133 * unsigned short update_crc_ccitt( unsigned long crc, char c ); *
134 * *
135 * The function update_crc_ccitt calculates a new CRC-CCITT *
136 * value based on the previous value of the CRC and the next *
137 * byte of the data to be checked. *
138 * *
139 \*******************************************************************/
140
141 unsigned short update_crc_ccitt( unsigned short crc, char c ) {
142
143 unsigned short tmp, short_c;
144
145 short_c = 0x00ff & (unsigned short) c;
146
147 if ( ! crc_tabccitt_init ) init_crcccitt_tab();
148
149 tmp = (crc >> 8) ^ short_c;
150 crc = (unsigned short)((crc << 8) ^ crc_tabccitt[tmp]);
151
152 return crc;
153
154 } /* update_crc_ccitt */
155
156
157
158 /*******************************************************************\
159 * *
160 * unsigned short update_crc_sick( *
161 * unsigned long crc, char c, char prev_byte ); *
162 * *
163 * The function update_crc_sick calculates a new CRC-SICK *
164 * value based on the previous value of the CRC and the next *
165 * byte of the data to be checked. *
166 * *
167 \*******************************************************************/
168
169 unsigned short update_crc_sick( unsigned short crc, char c, char prev_byte ) {
170
171 unsigned short short_c, short_p;
172
173 short_c = 0x00ff & (unsigned short) c;
174 short_p = (unsigned short)(( 0x00ff & (unsigned short) prev_byte ) << 8);
175
176 if ( crc & 0x8000 ) crc = (unsigned short)(( crc << 1 ) ^ P_SICK);
177 else crc = (unsigned short)(crc << 1);
178
179 crc &= 0xffff;
180 crc ^= ( short_c | short_p );
181
182 return crc;
183
184 } /* update_crc_sick */
185
186
187
188 /*******************************************************************\
189 * *
190 * unsigned short update_crc_16( unsigned short crc, char c ); *
191 * *
192 * The function update_crc_16 calculates a new CRC-16 value *
193 * based on the previous value of the CRC and the next byte *
194 * of the data to be checked. *
195 * *
196 \*******************************************************************/
197
198 unsigned short update_crc_16( unsigned short crc, char c ) {
199
200 unsigned short tmp, short_c;
201
202 short_c = 0x00ff & (unsigned short) c;
203
204 if ( ! crc_tab16_init ) init_crc16_tab();
205
206 tmp = crc ^ short_c;
207 // Note: when masking by 0xff, range is limited to unsigned char
208 // which fits within unsigned int.
209 crc = (crc >> 8) ^ crc_tab16[ (unsigned int)(tmp & 0xff) ];
210
211 return crc;
212
213 } /* update_crc_16 */
214
215
216
217 /*******************************************************************\
218 * *
219 * unsigned short update_crc_kermit( unsigned short crc, char c ); *
220 * *
221 * The function update_crc_kermit calculates a new CRC value *
222 * based on the previous value of the CRC and the next byte *
223 * of the data to be checked. *
224 * *
225 \*******************************************************************/
226
227 unsigned short update_crc_kermit( unsigned short crc, char c ) {
228
229 unsigned short tmp, short_c;
230
231 short_c = 0x00ff & (unsigned short) c;
232
233 if ( ! crc_tabkermit_init ) init_crckermit_tab();
234
235 tmp = crc ^ short_c;
236 crc = (crc >> 8) ^ crc_tabkermit[ tmp & 0xff ];
237
238 return crc;
239
240 } /* update_crc_kermit */
241
242
243
244 /*******************************************************************\
245 * *
246 * unsigned short update_crc_dnp( unsigned short crc, char c ); *
247 * *
248 * The function update_crc_dnp calculates a new CRC-DNP value *
249 * based on the previous value of the CRC and the next byte *
250 * of the data to be checked. *
251 * *
252 \*******************************************************************/
253
254 unsigned short update_crc_dnp( unsigned short crc, char c ) {
255
256 unsigned short tmp, short_c;
257
258 short_c = 0x00ff & (unsigned short) c;
259
260 if ( ! crc_tabdnp_init ) init_crcdnp_tab();
261
262 tmp = crc ^ short_c;
263 crc = (crc >> 8) ^ crc_tabdnp[ tmp & 0xff ];
264
265 return crc;
266
267 } /* update_crc_dnp */
268
269
270
271 /*******************************************************************\
272 * *
273 * unsigned long update_crc_32( unsigned long crc, char c ); *
274 * *
275 * The function update_crc_32 calculates a new CRC-32 value *
276 * based on the previous value of the CRC and the next byte *
277 * of the data to be checked. *
278 * *
279 \*******************************************************************/
280
281 // F PRIME CHANGE (see header)
282 #if 0
283 unsigned long update_crc_32( unsigned long crc, char c ) {
284
285 unsigned long tmp, long_c;
286
287 long_c = 0x000000ffL & (unsigned long) c;
288
289 if ( ! crc_tab32_init ) init_crc32_tab();
290
291 tmp = crc ^ long_c;
292 crc = (crc >> 8) ^ crc_tab32[ tmp & 0xff ];
293
294 return crc;
295
296 } /* update_crc_32 */
297 #endif
298
299
300
301 /*******************************************************************\
302 * *
303 * static void init_crc16_tab( void ); *
304 * *
305 * The function init_crc16_tab() is used to fill the array *
306 * for calculation of the CRC-16 with values. *
307 * *
308 \*******************************************************************/
309
310 static void init_crc16_tab( void ) {
311
312 int i, j;
313 unsigned short crc, c;
314
315 for (i=0; i<256; i++) {
316
317 crc = 0;
318 c = (unsigned short) i;
319
320 for (j=0; j<8; j++) {
321
322 if ( (crc ^ c) & 0x0001 ) crc = ( crc >> 1 ) ^ P_16;
323 else crc = crc >> 1;
324
325 c = c >> 1;
326 }
327
328 crc_tab16[i] = crc;
329 }
330
331 crc_tab16_init = CRC_TRUE;
332
333 } /* init_crc16_tab */
334
335
336
337 /*******************************************************************\
338 * *
339 * static void init_crckermit_tab( void ); *
340 * *
341 * The function init_crckermit_tab() is used to fill the array *
342 * for calculation of the CRC Kermit with values. *
343 * *
344 \*******************************************************************/
345
346 static void init_crckermit_tab( void ) {
347
348 int i, j;
349 unsigned short crc, c;
350
351 for (i=0; i<256; i++) {
352
353 crc = 0;
354 c = (unsigned short) i;
355
356 for (j=0; j<8; j++) {
357
358 if ( (crc ^ c) & 0x0001 ) crc = ( crc >> 1 ) ^ P_KERMIT;
359 else crc = crc >> 1;
360
361 c = c >> 1;
362 }
363
364 crc_tabkermit[i] = crc;
365 }
366
367 crc_tabkermit_init = CRC_TRUE;
368
369 } /* init_crckermit_tab */
370
371
372
373 /*******************************************************************\
374 * *
375 * static void init_crcdnp_tab( void ); *
376 * *
377 * The function init_crcdnp_tab() is used to fill the array *
378 * for calculation of the CRC-DNP with values. *
379 * *
380 \*******************************************************************/
381
382 static void init_crcdnp_tab( void ) {
383
384 int i, j;
385 unsigned short crc, c;
386
387 for (i=0; i<256; i++) {
388
389 crc = 0;
390 c = (unsigned short) i;
391
392 for (j=0; j<8; j++) {
393
394 if ( (crc ^ c) & 0x0001 ) crc = ( crc >> 1 ) ^ P_DNP;
395 else crc = crc >> 1;
396
397 c = c >> 1;
398 }
399
400 crc_tabdnp[i] = crc;
401 }
402
403 crc_tabdnp_init = CRC_TRUE;
404
405 } /* init_crcdnp_tab */
406
407
408
409 /*******************************************************************\
410 * *
411 * static void init_crc32_tab( void ); *
412 * *
413 * The function init_crc32_tab() is used to fill the array *
414 * for calculation of the CRC-32 with values. *
415 * *
416 \*******************************************************************/
417
418 // F PRIME CHANGE (see header)
419 #if 0
420 static void init_crc32_tab( void ) {
421
422 int i, j;
423 unsigned long crc;
424
425 for (i=0; i<256; i++) {
426
427 crc = (unsigned long) i;
428
429 for (j=0; j<8; j++) {
430
431 if ( crc & 0x00000001L ) crc = ( crc >> 1 ) ^ P_32;
432 else crc = crc >> 1;
433 }
434
435 crc_tab32[i] = crc;
436 }
437
438 crc_tab32_init = CRC_TRUE;
439
440 } /* init_crc32_tab */
441 #endif
442
443
444
445 /*******************************************************************\
446 * *
447 * static void init_crcccitt_tab( void ); *
448 * *
449 * The function init_crcccitt_tab() is used to fill the array *
450 * for calculation of the CRC-CCITT with values. *
451 * *
452 \*******************************************************************/
453
454 static void init_crcccitt_tab( void ) {
455
456 int i, j;
457 unsigned short crc, c;
458
459 for (i=0; i<256; i++) {
460
461 crc = 0;
462 c = (unsigned short)(((unsigned short) i) << 8);
463
464 for (j=0; j<8; j++) {
465
466 if ( (crc ^ c) & 0x8000 ) crc = (unsigned short)(( crc << 1 ) ^ P_CCITT);
467 else crc = (unsigned short)(crc << 1);
468
469 c = (unsigned short)(c << 1);
470 }
471
472 crc_tabccitt[i] = crc;
473 }
474
475 crc_tabccitt_init = CRC_TRUE;
476
477 } /* init_crcccitt_tab */
478