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

Last change on this file was 3, checked in by f.jahn, 20 months ago

fw hinzugfügt-->zed

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.