F´ Flight Software - C/C++ Documentation  devel
A framework for building embedded system applications to NASA flight quality standards.
tst_crc.c
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 
5 #include "lib_crc.h"
6 
7 
8 
9  /*******************************************************************\
10  * *
11  * Library : lib_crc *
12  * File : tst_crc.c *
13  * Author : Lammert Bies 1999-2008 *
14  * E-mail : info@lammertbies.nl *
15  * Language : ANSI C *
16  * *
17  * *
18  * Description *
19  * =========== *
20  * *
21  * The file tst_crc.c contains a small sample program which *
22  * demonstrates the use of the functions for calculating the *
23  * CRC-CCITT, CRC-16 and CRC-32 values of data. The file cal- *
24  * culates the three different CRC's for a file whose name is *
25  * either provided at the command line, or typed in right *
26  * after the program has started. *
27  * *
28  * *
29  * Dependencies *
30  * ============ *
31  * *
32  * lib_crc.h CRC definitions and prototypes *
33  * lib_crc.c CRC routines *
34  * *
35  * *
36  * Modification history *
37  * ==================== *
38  * *
39  * Date Version Comment *
40  * *
41  * 2008-04-20 1.16 Added CRC-CCITT calculation for Kermit. *
42  * *
43  * 2007-05-01 1.15 Added CRC16 calculation for Modbus. *
44  * *
45  * 2007-03-28 1.14 Added CRC16 routine for Sick devices, *
46  * electronic devices used for measurement *
47  * and detection in industrial situations. *
48  * *
49  * 2005-12-17 1.13 Added CRC-CCITT with initial 0x1D0F *
50  * *
51  * 2005-02-14 1.12 Added CRC-CCITT with initial 0x0000 *
52  * *
53  * 2005-02-05 1.11 Fixed post processing bug in CRC-DNP. *
54  * *
55  * 2005-02-04 1.10 Added the CRC calculation for DNP 3.0, *
56  * a protocol used in the communication *
57  * between remote units and masters in the *
58  * electric utility industry. The method *
59  * of calculation is the same as CRC-16, *
60  * but with a different polynomial. *
61  * *
62  * 2005-01-07 1.02 Changed way program is used. When a *
63  * commandline parameter is present, the *
64  * program assumes it is a file, but when *
65  * invoked without a parameter the entered *
66  * string is used to calculate the CRC. *
67  * *
68  * CRC's are now printed in hexadecimal *
69  * decimal format. *
70  * *
71  * Let CRC-CCITT calculation start with *
72  * 0xffff as this is used in most imple- *
73  * mentations. *
74  * *
75  * 1999-02-21 1.01 none *
76  * *
77  * 1999-01-22 1.00 Initial source *
78  * *
79  \*******************************************************************/
80 
81 #define MAX_STRING_SIZE 2048
82 
83 
84 
85 void main( int argc, char *argv[] ) {
86 
87  char input_string[MAX_STRING_SIZE];
88  char *ptr, *dest, hex_val, prev_byte;
89  unsigned short crc_16, crc_16_modbus, crc_ccitt_ffff, crc_ccitt_0000, crc_ccitt_1d0f, crc_dnp, crc_sick, crc_kermit;
90  unsigned short low_byte, high_byte;
91  unsigned long crc_32;
92  int a, ch, do_ascii, do_hex;
93  FILE *fp;
94 
95  do_ascii = CRC_FALSE;
96  do_hex = CRC_FALSE;
97 
98  printf( "\nCRC algorithm sample program\nLammert Bies, Version " CRC_VERSION "\n\n" );
99 
100  if ( argc < 2 ) {
101 
102  printf( "Usage: tst_crc [-a|-x] file1 ...\n\n" );
103  printf( " -a Program asks for ASCII input. Following parameters ignored.\n" );
104  printf( " -x Program asks for hexadecimal input. Following parameters ignored.\n" );
105  printf( " All other parameters are treated like filenames. The CRC values\n" );
106  printf( " for each separate file will be calculated.\n" );
107 
108  exit( 0 );
109  }
110 
111  if ( ! strcmp( argv[1], "-a" ) || ! strcmp( argv[1], "-A" ) ) do_ascii = CRC_TRUE;
112  if ( ! strcmp( argv[1], "-x" ) || ! strcmp( argv[1], "-X" ) ) do_hex = CRC_TRUE;
113 
114  if ( do_ascii || do_hex ) {
115 
116  printf( "Input: " );
117  fgets( input_string, MAX_STRING_SIZE-1, stdin );
118  }
119 
120  if ( do_ascii ) {
121 
122  ptr = input_string;
123  while ( *ptr && *ptr != '\r' && *ptr != '\n' ) ptr++;
124  *ptr = 0;
125  }
126 
127  if ( do_hex ) {
128 
129  ptr = input_string;
130  dest = input_string;
131 
132  while( *ptr && *ptr != '\r' && *ptr != '\n' ) {
133 
134  if ( *ptr >= '0' && *ptr <= '9' ) *dest++ = (char) ( (*ptr) - '0' );
135  if ( *ptr >= 'A' && *ptr <= 'F' ) *dest++ = (char) ( (*ptr) - 'A' + 10 );
136  if ( *ptr >= 'a' && *ptr <= 'f' ) *dest++ = (char) ( (*ptr) - 'a' + 10 );
137 
138  ptr++;
139  }
140 
141  * dest = '\x80';
142  *(dest+1) = '\x80';
143  }
144 
145 
146 
147  a = 1;
148 
149  do {
150 
151  crc_16 = 0;
152  crc_16_modbus = 0xffff;
153  crc_dnp = 0;
154  crc_sick = 0;
155  crc_ccitt_0000 = 0;
156  crc_ccitt_ffff = 0xffff;
157  crc_ccitt_1d0f = 0x1d0f;
158  crc_kermit = 0;
159  crc_32 = 0xffffffffL;
160 
161 
162 
163  if ( do_ascii ) {
164 
165  prev_byte = 0;
166  ptr = input_string;
167 
168  while ( *ptr ) {
169 
170  crc_16 = update_crc_16( crc_16, *ptr );
171  crc_16_modbus = update_crc_16( crc_16_modbus, *ptr );
172  crc_dnp = update_crc_dnp( crc_dnp, *ptr );
173  crc_sick = update_crc_sick( crc_sick, *ptr, prev_byte );
174  crc_ccitt_0000 = update_crc_ccitt( crc_ccitt_0000, *ptr );
175  crc_ccitt_ffff = update_crc_ccitt( crc_ccitt_ffff, *ptr );
176  crc_ccitt_1d0f = update_crc_ccitt( crc_ccitt_1d0f, *ptr );
177  crc_kermit = update_crc_kermit( crc_kermit, *ptr );
178  crc_32 = update_crc_32( crc_32, *ptr );
179 
180  prev_byte = *ptr;
181  ptr++;
182  }
183  }
184 
185 
186 
187  else if ( do_hex ) {
188 
189  prev_byte = 0;
190  ptr = input_string;
191 
192  while ( *ptr != '\x80' ) {
193 
194  hex_val = (char) ( ( * ptr & '\x0f' ) << 4 );
195  hex_val |= (char) ( ( *(ptr+1) & '\x0f' ) );
196 
197  crc_16 = update_crc_16( crc_16, hex_val );
198  crc_16_modbus = update_crc_16( crc_16_modbus, hex_val );
199  crc_dnp = update_crc_dnp( crc_dnp, hex_val );
200  crc_sick = update_crc_sick( crc_sick, hex_val, prev_byte );
201  crc_ccitt_0000 = update_crc_ccitt( crc_ccitt_0000, hex_val );
202  crc_ccitt_ffff = update_crc_ccitt( crc_ccitt_ffff, hex_val );
203  crc_ccitt_1d0f = update_crc_ccitt( crc_ccitt_1d0f, hex_val );
204  crc_kermit = update_crc_kermit( crc_kermit, hex_val );
205  crc_32 = update_crc_32( crc_32, hex_val );
206 
207  prev_byte = hex_val;
208  ptr += 2;
209  }
210 
211  input_string[0] = 0;
212  }
213 
214 
215 
216  else {
217 
218  prev_byte = 0;
219  fp = fopen( argv[a], "rb" );
220 
221  if ( fp != nullptr ) {
222 
223  while( ( ch=fgetc( fp ) ) != EOF ) {
224 
225  crc_16 = update_crc_16( crc_16, (char) ch );
226  crc_16_modbus = update_crc_16( crc_16_modbus, (char) ch );
227  crc_dnp = update_crc_dnp( crc_dnp, (char) ch );
228  crc_sick = update_crc_sick( crc_sick, (char) ch, prev_byte );
229  crc_ccitt_0000 = update_crc_ccitt( crc_ccitt_0000, (char) ch );
230  crc_ccitt_ffff = update_crc_ccitt( crc_ccitt_ffff, (char) ch );
231  crc_ccitt_1d0f = update_crc_ccitt( crc_ccitt_1d0f, (char) ch );
232  crc_kermit = update_crc_kermit( crc_kermit, (char) ch );
233  crc_32 = update_crc_32( crc_32, (char) ch );
234 
235  prev_byte = (char) ch;
236  }
237 
238  fclose( fp );
239  }
240 
241  else printf( "%s : cannot open file\n", argv[a] );
242  }
243 
244 
245 
246  crc_32 ^= 0xffffffffL;
247 
248  crc_dnp = ~crc_dnp;
249  low_byte = (crc_dnp & 0xff00) >> 8;
250  high_byte = (crc_dnp & 0x00ff) << 8;
251  crc_dnp = low_byte | high_byte;
252 
253  low_byte = (crc_sick & 0xff00) >> 8;
254  high_byte = (crc_sick & 0x00ff) << 8;
255  crc_sick = low_byte | high_byte;
256 
257  low_byte = (crc_kermit & 0xff00) >> 8;
258  high_byte = (crc_kermit & 0x00ff) << 8;
259  crc_kermit = low_byte | high_byte;
260 
261  printf( "%s%s%s :\nCRC16 = 0x%04X / %u\n"
262  "CRC16 (Modbus) = 0x%04X / %u\n"
263  "CRC16 (Sick) = 0x%04X / %u\n"
264  "CRC-CCITT (0x0000) = 0x%04X / %u\n"
265  "CRC-CCITT (0xffff) = 0x%04X / %u\n"
266  "CRC-CCITT (0x1d0f) = 0x%04X / %u\n"
267  "CRC-CCITT (Kermit) = 0x%04X / %u\n"
268  "CRC-DNP = 0x%04X / %u\n"
269  "CRC32 = 0x%08lX / %lu\n"
270  , ( do_ascii || do_hex ) ? "\"" : ""
271  , ( ! do_ascii && ! do_hex ) ? argv[a] : input_string
272  , ( do_ascii || do_hex ) ? "\"" : ""
273  , crc_16, crc_16
274  , crc_16_modbus, crc_16_modbus
275  , crc_sick, crc_sick
276  , crc_ccitt_0000, crc_ccitt_0000
277  , crc_ccitt_ffff, crc_ccitt_ffff
278  , crc_ccitt_1d0f, crc_ccitt_1d0f
279  , crc_kermit, crc_kermit
280  , crc_dnp, crc_dnp
281  , crc_32, crc_32 );
282 
283  a++;
284 
285  } while ( a < argc );
286 
287 } /* main (tst_crc.c) */
unsigned short update_crc_ccitt(unsigned short crc, char c)
Definition: lib_crc.c:131
unsigned short update_crc_kermit(unsigned short crc, char c)
Definition: lib_crc.c:217
unsigned short update_crc_sick(unsigned short crc, char c, char prev_byte)
Definition: lib_crc.c:159
unsigned long update_crc_32(unsigned long crc, char c)
Definition: lib_crc.c:271
unsigned short update_crc_dnp(unsigned short crc, char c)
Definition: lib_crc.c:244
unsigned short update_crc_16(unsigned short crc, char c)
Definition: lib_crc.c:188
#define CRC_VERSION
Definition: lib_crc.h:57
#define CRC_FALSE
Definition: lib_crc.h:61
#define CRC_TRUE
Definition: lib_crc.h:62
#define MAX_STRING_SIZE
Definition: tst_crc.c:81
void main(int argc, char *argv[])
Definition: tst_crc.c:85