source: trunk/tools/FileEncrypt/src/crc.c

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