tstcrc.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. /*
  2. * Library: libcrc
  3. * File: examples/tstcrc.c
  4. * Author: Lammert Bies
  5. *
  6. * This file is licensed under the MIT License as stated below
  7. *
  8. * Copyright (c) 1999-2016 Lammert Bies
  9. *
  10. * Permission is hereby granted, free of charge, to any person obtaining a copy
  11. * of this software and associated documentation files (the "Software"), to deal
  12. * in the Software without restriction, including without limitation the rights
  13. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  14. * copies of the Software, and to permit persons to whom the Software is
  15. * furnished to do so, subject to the following conditions:
  16. *
  17. * The above copyright notice and this permission notice shall be included in all
  18. * copies or substantial portions of the Software.
  19. *
  20. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  21. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  22. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  23. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  24. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  25. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  26. * SOFTWARE.
  27. *
  28. * Description
  29. * -----------
  30. * The file tstx_crc.c contains a small sample program which demonstrates the
  31. * use of the functions for calculating the CRC-CCITT, CRC-16 and CRC-32 values
  32. * of data. The program calculates the three different CRC's for a file who's
  33. * name is either provided at the command line, or data typed in right the
  34. * program has started.
  35. */
  36. #include <inttypes.h>
  37. #include <stdbool.h>
  38. #include <stdint.h>
  39. #include <stdio.h>
  40. #include <stdlib.h>
  41. #include <string.h>
  42. #include "../include/checksum.h"
  43. #define MAX_STRING_SIZE 2048
  44. /*
  45. * int main( int argc, char *argv[] );
  46. *
  47. * The function main() is the entry point of the example program which
  48. * calculates several CRC values from the contents of files, or data from
  49. * stdin.
  50. */
  51. int main( int argc, char *argv[] ) {
  52. char input_string[MAX_STRING_SIZE];
  53. unsigned char *ptr;
  54. unsigned char *dest;
  55. unsigned char hex_val;
  56. unsigned char prev_byte;
  57. uint16_t crc_16_val;
  58. uint16_t crc_16_modbus_val;
  59. uint16_t crc_ccitt_ffff_val;
  60. uint16_t crc_ccitt_0000_val;
  61. uint16_t crc_ccitt_1d0f_val;
  62. uint16_t crc_dnp_val;
  63. uint16_t crc_sick_val;
  64. uint16_t crc_kermit_val;
  65. uint32_t crc_32_val;
  66. uint16_t low_byte;
  67. uint16_t high_byte;
  68. int a;
  69. int ch;
  70. bool do_ascii;
  71. bool do_hex;
  72. FILE *fp;
  73. do_ascii = false;
  74. do_hex = false;
  75. printf( "\ntstcrc: CRC algorithm sample program\nCopyright (c) 1999-2016 Lammert Bies\n\n" );
  76. if ( argc < 2 ) {
  77. printf( "Usage: tst_crc [-a|-x] file1 ...\n\n" );
  78. printf( " -a Program asks for ASCII input. Following parameters ignored.\n" );
  79. printf( " -x Program asks for hexadecimal input. Following parameters ignored.\n" );
  80. printf( " All other parameters are treated like filenames. The CRC values\n" );
  81. printf( " for each separate file will be calculated.\n" );
  82. exit( 0 );
  83. }
  84. if ( ! strcmp( argv[1], "-a" ) || ! strcmp( argv[1], "-A" ) ) do_ascii = true;
  85. if ( ! strcmp( argv[1], "-x" ) || ! strcmp( argv[1], "-X" ) ) do_hex = true;
  86. if ( do_ascii || do_hex ) {
  87. printf( "Input: " );
  88. if( fgets( input_string, MAX_STRING_SIZE-1, stdin ) == NULL ){
  89. // Print the error
  90. perror("Error");
  91. }
  92. }
  93. if ( do_ascii ) {
  94. ptr = (unsigned char *) input_string;
  95. while ( *ptr && *ptr != '\r' && *ptr != '\n' ) ptr++;
  96. *ptr = 0;
  97. }
  98. if ( do_hex ) {
  99. ptr = (unsigned char *) input_string;
  100. dest = (unsigned char *) input_string;
  101. while( *ptr && *ptr != '\r' && *ptr != '\n' ) {
  102. if ( *ptr >= '0' && *ptr <= '9' ) *dest++ = (unsigned char) ( (*ptr) - '0' );
  103. if ( *ptr >= 'A' && *ptr <= 'F' ) *dest++ = (unsigned char) ( (*ptr) - 'A' + 10 );
  104. if ( *ptr >= 'a' && *ptr <= 'f' ) *dest++ = (unsigned char) ( (*ptr) - 'a' + 10 );
  105. ptr++;
  106. }
  107. * dest = '\x80';
  108. *(dest+1) = '\x80';
  109. }
  110. a = 1;
  111. do {
  112. crc_16_val = 0x0000;
  113. crc_16_modbus_val = 0xffff;
  114. crc_dnp_val = 0x0000;
  115. crc_sick_val = 0x0000;
  116. crc_ccitt_0000_val = 0x0000;
  117. crc_ccitt_ffff_val = 0xffff;
  118. crc_ccitt_1d0f_val = 0x1d0f;
  119. crc_kermit_val = 0x0000;
  120. crc_32_val = 0xffffffffL;
  121. if ( do_ascii ) {
  122. prev_byte = 0;
  123. ptr = (unsigned char *) input_string;
  124. while ( *ptr ) {
  125. crc_16_val = update_crc_16( crc_16_val, *ptr );
  126. crc_16_modbus_val = update_crc_16( crc_16_modbus_val, *ptr );
  127. crc_dnp_val = update_crc_dnp( crc_dnp_val, *ptr );
  128. crc_sick_val = update_crc_sick( crc_sick_val, *ptr, prev_byte );
  129. crc_ccitt_0000_val = update_crc_ccitt( crc_ccitt_0000_val, *ptr );
  130. crc_ccitt_ffff_val = update_crc_ccitt( crc_ccitt_ffff_val, *ptr );
  131. crc_ccitt_1d0f_val = update_crc_ccitt( crc_ccitt_1d0f_val, *ptr );
  132. crc_kermit_val = update_crc_kermit( crc_kermit_val, *ptr );
  133. crc_32_val = update_crc_32( crc_32_val, *ptr );
  134. prev_byte = *ptr;
  135. ptr++;
  136. }
  137. }
  138. else if ( do_hex ) {
  139. prev_byte = 0;
  140. ptr = (unsigned char *) input_string;
  141. while ( *ptr != '\x80' ) {
  142. hex_val = (unsigned char) ( ( * ptr & '\x0f' ) << 4 );
  143. hex_val |= (unsigned char) ( ( *(ptr+1) & '\x0f' ) );
  144. crc_16_val = update_crc_16( crc_16_val, hex_val );
  145. crc_16_modbus_val = update_crc_16( crc_16_modbus_val, hex_val );
  146. crc_dnp_val = update_crc_dnp( crc_dnp_val, hex_val );
  147. crc_sick_val = update_crc_sick( crc_sick_val, hex_val, prev_byte );
  148. crc_ccitt_0000_val = update_crc_ccitt( crc_ccitt_0000_val, hex_val );
  149. crc_ccitt_ffff_val = update_crc_ccitt( crc_ccitt_ffff_val, hex_val );
  150. crc_ccitt_1d0f_val = update_crc_ccitt( crc_ccitt_1d0f_val, hex_val );
  151. crc_kermit_val = update_crc_kermit( crc_kermit_val, hex_val );
  152. crc_32_val = update_crc_32( crc_32_val, hex_val );
  153. prev_byte = hex_val;
  154. ptr += 2;
  155. }
  156. input_string[0] = 0;
  157. }
  158. else {
  159. prev_byte = 0;
  160. #if defined(_MSC_VER)
  161. fp = NULL;
  162. fopen_s( & fp, argv[a], "rb" );
  163. #else
  164. fp = fopen( argv[a], "rb" );
  165. #endif
  166. if ( fp != NULL ) {
  167. while( ( ch=fgetc( fp ) ) != EOF ) {
  168. crc_16_val = update_crc_16( crc_16_val, (unsigned char) ch );
  169. crc_16_modbus_val = update_crc_16( crc_16_modbus_val, (unsigned char) ch );
  170. crc_dnp_val = update_crc_dnp( crc_dnp_val, (unsigned char) ch );
  171. crc_sick_val = update_crc_sick( crc_sick_val, (unsigned char) ch, prev_byte );
  172. crc_ccitt_0000_val = update_crc_ccitt( crc_ccitt_0000_val, (unsigned char) ch );
  173. crc_ccitt_ffff_val = update_crc_ccitt( crc_ccitt_ffff_val, (unsigned char) ch );
  174. crc_ccitt_1d0f_val = update_crc_ccitt( crc_ccitt_1d0f_val, (unsigned char) ch );
  175. crc_kermit_val = update_crc_kermit( crc_kermit_val, (unsigned char) ch );
  176. crc_32_val = update_crc_32( crc_32_val, (unsigned char) ch );
  177. prev_byte = (unsigned char) ch;
  178. }
  179. fclose( fp );
  180. }
  181. else printf( "%s : cannot open file\n", argv[a] );
  182. }
  183. crc_32_val ^= 0xffffffffL;
  184. crc_dnp_val = ~crc_dnp_val;
  185. low_byte = (crc_dnp_val & 0xff00) >> 8;
  186. high_byte = (crc_dnp_val & 0x00ff) << 8;
  187. crc_dnp_val = low_byte | high_byte;
  188. low_byte = (crc_sick_val & 0xff00) >> 8;
  189. high_byte = (crc_sick_val & 0x00ff) << 8;
  190. crc_sick_val = low_byte | high_byte;
  191. low_byte = (crc_kermit_val & 0xff00) >> 8;
  192. high_byte = (crc_kermit_val & 0x00ff) << 8;
  193. crc_kermit_val = low_byte | high_byte;
  194. printf( "%s%s%s :\nCRC16 = 0x%04" PRIX16 " / %" PRIu16 "\n"
  195. "CRC16 (Modbus) = 0x%04" PRIX16 " / %" PRIu16 "\n"
  196. "CRC16 (Sick) = 0x%04" PRIX16 " / %" PRIu16 "\n"
  197. "CRC-CCITT (0x0000) = 0x%04" PRIX16 " / %" PRIu16 "\n"
  198. "CRC-CCITT (0xffff) = 0x%04" PRIX16 " / %" PRIu16 "\n"
  199. "CRC-CCITT (0x1d0f) = 0x%04" PRIX16 " / %" PRIu16 "\n"
  200. "CRC-CCITT (Kermit) = 0x%04" PRIX16 " / %" PRIu16 "\n"
  201. "CRC-DNP = 0x%04" PRIX16 " / %" PRIu16 "\n"
  202. "CRC32 = 0x%08" PRIX32 " / %" PRIu32 "\n"
  203. , ( do_ascii || do_hex ) ? "\"" : ""
  204. , ( ! do_ascii && ! do_hex ) ? argv[a] : input_string
  205. , ( do_ascii || do_hex ) ? "\"" : ""
  206. , crc_16_val, crc_16_val
  207. , crc_16_modbus_val, crc_16_modbus_val
  208. , crc_sick_val, crc_sick_val
  209. , crc_ccitt_0000_val, crc_ccitt_0000_val
  210. , crc_ccitt_ffff_val, crc_ccitt_ffff_val
  211. , crc_ccitt_1d0f_val, crc_ccitt_1d0f_val
  212. , crc_kermit_val, crc_kermit_val
  213. , crc_dnp_val, crc_dnp_val
  214. , crc_32_val, crc_32_val );
  215. a++;
  216. } while ( a < argc );
  217. return 0;
  218. } /* main (tstcrc.c) */