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