CRC 最全算法库

 

该算法库支持如下编码

   CRC16

   CRC16 Modbus

   CRC16 SICK  

   CRC-CCITT (starting value 0x0000)
   CRC-CCITT (starting value 0xFFFF)
   CRC-CCITT (starting value 0x1D0F)
   CRC-Kermit    

   CRC-DNP   

   CRC32 

 

将如下三个文件lib_crc.c lib_crc.h tst_crc.c编译,并按照如下说明书运行即可生成上述编码。

如要下载该编码库 ,请访问

http://www.lammertbies.nl/comm/software/index.html

 

如要在线生成CRC编码,请访问

 

http://www.lammertbies.nl/comm/info/crc-calculation.html

 

 

 

说明书

 


   File      : lib_crc.txt
   Date      : 2008-04-20
   Author    : Lammert Bies
   E-mail    : info@lammertbies.nl
   Version   : 1.16

   Contents  : Documentation for the CRC functions in lib_crc.c

   Support   : http://www.lammertbies.nl/forum/viewforum.php?f=11

 

   The file lib_crc.c contains source code for functions to calculate
   five commonly used CRC values: CRC-16, CRC-32, CRC-DNP, CRC-SICK,
   CRC-Kermit and CRC-CCITT. The functions can be freely used.

   To calculate a CRC, the following three steps must be followed:

   1. Initialize the CRC value. For CRC-16, CRC-SICK CRC-Kermit and CRC-DNP
      the initial value of the CRC is 0. For CRC-CCITT and CRC-MODBUS,
      the value 0xffff is used. CRC-32 starts with an initial value
      of 0xffffffffL.

   2. For each byte of the data starting with the first byte, call the
      function update_crc_16(), update_crc_32(), update_crc_dnp(),
      update_crc_sick(), update_crc_kermit() or update_crc_ccitt()
      to recalculate the value of the CRC.

   3. Only for CRC-32: When all bytes have been processed, take the
      one's complement of the obtained CRC value.

   4. Only for CRC-DNP: After all input processing, the one's complement
      of the CRC is calcluated and the two bytes of the CRC are swapped.

   5. Only for CRC-Kermit and CRC-SICK: After all input processing, the
      one's complement of the CRC is calcluated and the two bytes of the CRC
      are swapped.

 

   An example of this calculation process can be found in the tst_crc.c
   sample program. The program and other CRC implementations can be
   tested with the test string "123456789" without the quotes. The
   results should be:

   CRC16        : BB3D
   CRC16 Modbus : 4B37
   CRC16 SICK   : 56A6
   CRC-CCITT    : 0x31C3 (starting value 0x0000)
   CRC-CCITT    : 0x29B1 (starting value 0xFFFF)
   CRC-CCITT    : 0xE5CC (starting value 0x1D0F)
   CRC-Kermit   : 0x8921
   CRC-DNP      : 82EA
   CRC32        : CBF43926

 

   The example program tst_crc.exe can be invoked in three ways:

   tst_crc -a

      The program will prompt for an input string. All characters in the
      input string are used for the CRC calculation, based on their ASCII
      value.

      Example input string: ABC
         CRC16              = 0x4521
         CRC16 (Modbus)     = 0x8550
         CRC16 (Sick)       = 0xC3C1
         CRC-CCITT (0x0000) = 0x3994
         CRC-CCITT (0xffff) = 0xF508
         CRC-CCITT (0x1d0f) = 0x2898
         CRC-CCITT (Kermit) = 0xE359
         CRC-DNP            = 0x5AD3
         CRC32              = 0xA3830348

   tst_crc -x

      The program will prompt for an input string. All characters will
      be filtered out, except for 0..9, a..f and A..F. The remaining characters
      will be paired, and every pair of two characters represent the hexadecimal
      value to be used for one byte in the CRC calculation. The result if an
      od number of valud characters is provided is undefined.

      Example input string: 41 42 43
         CRC16              = 0x4521
         CRC16 (Modbus)     = 0x8550
         CRC16 (Sick)       = 0xC3C1
         CRC-CCITT (0x0000) = 0x3994
         CRC-CCITT (0xffff) = 0xF508
         CRC-CCITT (0x1d0f) = 0x2898
         CRC-CCITT (Kermit) = 0xE359
         CRC-DNP            = 0x5AD3
         CRC32              = 0xA3830348

      You see, that the result is the same as for the ASCII input "ABC". This
      is, because A, B and C are represented in ASCII by the hexadecimal
      values 41, 42 and 43. So it is obvious that the result should be
      the same in both cases.

   tst_crc file1 file2 ...

      If neither the -a, nor the -x parameter is used, the test program
      assumes that the parameters are file names. Each file is opened and
      the CRC values are calculated.

 

   The newest version of these files can be found at:

        http://www.lammertbies.nl/download/lib_crc.zip

   On-line CRC calculations of strings can be performed at:

        http://www.lammertbies.nl/comm/info/crc-calculation.html

   Support for the CRC routines in this library in the Error Detection and
   Correction forum at

        http://www.lammertbies.nl/forum/viewforum.php?f=11

 

 

lib_crc.h

    /*******************************************************************\
    *                                                                   *
    *   Library         : lib_crc                                       *
    *   File            : lib_crc.h                                     *
    *   Author          : Lammert Bies  1999-2008                       *
    *   E-mail          : info@lammertbies.nl                           *
    *   Language        : ANSI C                                        *
    *                                                                   *
    *                                                                   *
    *   Description                                                     *
    *   ===========                                                     *
    *                                                                   *
    *   The file lib_crc.h contains public definitions  and  proto-     *
    *   types for the CRC functions present in lib_crc.c.               *
    *                                                                   *
    *                                                                   *
    *   Dependencies                                                    *
    *   ============                                                    *
    *                                                                   *
    *   none                                                            *
    *                                                                   *
    *                                                                   *
    *   Modification history                                            *
    *   ====================                                            *
    *                                                                   *
    *   Date        Version Comment                                     *
    *                                                                   *
    *   2008-04-20  1.16    Added CRC-CCITT routine for Kermit          *
    *                                                                   *
    *   2007-04-01  1.15    Added CRC16 calculation for Modbus          *
    *                                                                   *
    *   2007-03-28  1.14    Added CRC16 routine for Sick devices        *
    *                                                                   *
    *   2005-12-17  1.13    Added CRC-CCITT with initial 0x1D0F         *
    *                                                                   *
    *   2005-02-14  1.12    Added CRC-CCITT with initial 0x0000         *
    *                                                                   *
    *   2005-02-05  1.11    Fixed bug in CRC-DNP routine                *
    *                                                                   *
    *   2005-02-04  1.10    Added CRC-DNP routines                      *
    *                                                                   *
    *   2005-01-07  1.02    Changes in tst_crc.c                        *
    *                                                                   *
    *   1999-02-21  1.01    Added FALSE and TRUE mnemonics              *
    *                                                                   *
    *   1999-01-22  1.00    Initial source                              *
    *                                                                   *
    \*******************************************************************/

 

#define CRC_VERSION     "1.16"

 

#define FALSE           0
#define TRUE            1

 

unsigned short          update_crc_16(     unsigned short crc, char c                 );
unsigned long           update_crc_32(     unsigned long  crc, char c                 );
unsigned short          update_crc_ccitt(  unsigned short crc, char c                 );
unsigned short          update_crc_dnp(    unsigned short crc, char c                 );
unsigned short          update_crc_kermit( unsigned short crc, char c                 );
unsigned short          update_crc_sick(   unsigned short crc, char c, char prev_byte );

 

lib_crc.c

 

 

 

#include "lib_crc.h"

 

    /*******************************************************************\
    *                                                                   *
    *   Library         : lib_crc                                       *
    *   File            : lib_crc.c                                     *
    *   Author          : Lammert Bies  1999-2008                       *
    *   E-mail          : info@lammertbies.nl                           *
    *   Language        : ANSI C                                        *
    *                                                                   *
    *                                                                   *
    *   Description                                                     *
    *   ===========                                                     *
    *                                                                   *
    *   The file lib_crc.c contains the private  and  public  func-     *
    *   tions  used  for  the  calculation of CRC-16, CRC-CCITT and     *
    *   CRC-32 cyclic redundancy values.                                *
    *                                                                   *
    *                                                                   *
    *   Dependencies                                                    *
    *   ============                                                    *
    *                                                                   *
    *   lib_crc.h       CRC definitions and prototypes                  *
    *                                                                   *
    *                                                                   *
    *   Modification history                                            *
    *   ====================                                            *
    *                                                                   *
    *   Date        Version Comment                                     *
    *                                                                   *
    *   2008-04-20  1.16    Added CRC-CCITT calculation for Kermit      *
    *                                                                   *
    *   2007-04-01  1.15    Added CRC16 calculation for Modbus          *
    *                                                                   *
    *   2007-03-28  1.14    Added CRC16 routine for Sick devices        *
    *                                                                   *
    *   2005-12-17  1.13    Added CRC-CCITT with initial 0x1D0F         *
    *                                                                   *
    *   2005-05-14  1.12    Added CRC-CCITT with start value 0          *
    *                                                                   *
    *   2005-02-05  1.11    Fixed bug in CRC-DNP routine                *
    *                                                                   *
    *   2005-02-04  1.10    Added CRC-DNP routines                      *
    *                                                                   *
    *   1999-02-21  1.01    Added FALSE and TRUE mnemonics              *
    *                                                                   *
    *   1999-01-22  1.00    Initial source                              *
    *                                                                   *
    \*******************************************************************/

 

    /*******************************************************************\
    *                                                                   *
    *   #define P_xxxx                                                  *
    *                                                                   *
    *   The CRC's are computed using polynomials. The  coefficients     *
    *   for the algorithms are defined by the following constants.      *
    *                                                                   *
    \*******************************************************************/

#define                 P_16        0xA001
#define                 P_32        0xEDB88320L
#define                 P_CCITT     0x1021
#define                 P_DNP       0xA6BC
#define                 P_KERMIT    0x8408
#define                 P_SICK      0x8005

 

    /*******************************************************************\
    *                                                                   *
    *   static int crc_tab...init                                       *
    *   static unsigned ... crc_tab...[]                                *
    *                                                                   *
    *   The algorithms use tables with precalculated  values.  This     *
    *   speeds  up  the calculation dramaticaly. The first time the     *
    *   CRC function is called, the table for that specific  calcu-     *
    *   lation  is set up. The ...init variables are used to deter-     *
    *   mine if the initialization has taken place. The  calculated     *
    *   values are stored in the crc_tab... arrays.                     *
    *                                                                   *
    *   The variables are declared static. This makes them  invisi-     *
    *   ble for other modules of the program.                           *
    *                                                                   *
    \*******************************************************************/

static int              crc_tab16_init          = FALSE;
static int              crc_tab32_init          = FALSE;
static int              crc_tabccitt_init       = FALSE;
static int              crc_tabdnp_init         = FALSE;
static int              crc_tabkermit_init      = FALSE;

static unsigned short   crc_tab16[256];
static unsigned long    crc_tab32[256];
static unsigned short   crc_tabccitt[256];
static unsigned short   crc_tabdnp[256];
static unsigned short   crc_tabkermit[256];

 

    /*******************************************************************\
    *                                                                   *
    *   static void init_crc...tab();                                   *
    *                                                                   *
    *   Three local functions are used  to  initialize  the  tables     *
    *   with values for the algorithm.                                  *
    *                                                                   *
    \*******************************************************************/

static void             init_crc16_tab( void );
static void             init_crc32_tab( void );
static void             init_crcccitt_tab( void );
static void             init_crcdnp_tab( void );
static void             init_crckermit_tab( void );

 

    /*******************************************************************\
    *                                                                   *
    *   unsigned short update_crc_ccitt( unsigned long crc, char c );   *
    *                                                                   *
    *   The function update_crc_ccitt calculates  a  new  CRC-CCITT     *
    *   value  based  on the previous value of the CRC and the next     *
    *   byte of the data to be checked.                                 *
    *                                                                   *
    \*******************************************************************/

unsigned short update_crc_ccitt( unsigned short crc, char c ) {

    unsigned short tmp, short_c;

    short_c  = 0x00ff & (unsigned short) c;

    if ( ! crc_tabccitt_init ) init_crcccitt_tab();

    tmp = (crc >> 8) ^ short_c;
    crc = (crc << 8) ^ crc_tabccitt[tmp];

    return crc;

}  /* update_crc_ccitt */

 

    /*******************************************************************\
    *                                                                   *
    *   unsigned short update_crc_sick(                                 *
    *             unsigned long crc, char c, char prev_byte );          *
    *                                                                   *
    *   The function  update_crc_sick  calculates  a  new  CRC-SICK     *
    *   value  based  on the previous value of the CRC and the next     *
    *   byte of the data to be checked.                                 *
    *                                                                   *
    \*******************************************************************/

unsigned short update_crc_sick( unsigned short crc, char c, char prev_byte ) {

    unsigned short short_c, short_p;

    short_c  =   0x00ff & (unsigned short) c;
    short_p  = ( 0x00ff & (unsigned short) prev_byte ) << 8;

    if ( crc & 0x8000 ) crc = ( crc << 1 ) ^ P_SICK;
    else                crc =   crc << 1;

    crc &= 0xffff;
    crc ^= ( short_c | short_p );

    return crc;

}  /* update_crc_sick */

 

    /*******************************************************************\
    *                                                                   *
    *   unsigned short update_crc_16( unsigned short crc, char c );     *
    *                                                                   *
    *   The function update_crc_16 calculates a  new  CRC-16  value     *
    *   based  on  the  previous value of the CRC and the next byte     *
    *   of the data to be checked.                                      *
    *                                                                   *
    \*******************************************************************/

unsigned short update_crc_16( unsigned short crc, char c ) {

    unsigned short tmp, short_c;

    short_c = 0x00ff & (unsigned short) c;

    if ( ! crc_tab16_init ) init_crc16_tab();

    tmp =  crc       ^ short_c;
    crc = (crc >> 8) ^ crc_tab16[ tmp & 0xff ];

    return crc;

}  /* update_crc_16 */

 

    /*******************************************************************\
    *                                                                   *
    *   unsigned short update_crc_kermit( unsigned short crc, char c ); *
    *                                                                   *
    *   The function update_crc_kermit calculates a  new  CRC value     *
    *   based  on  the  previous value of the CRC and the next byte     *
    *   of the data to be checked.                                      *
    *                                                                   *
    \*******************************************************************/

unsigned short update_crc_kermit( unsigned short crc, char c ) {

    unsigned short tmp, short_c;

    short_c = 0x00ff & (unsigned short) c;

    if ( ! crc_tabkermit_init ) init_crckermit_tab();

    tmp =  crc       ^ short_c;
    crc = (crc >> 8) ^ crc_tabkermit[ tmp & 0xff ];

    return crc;

}  /* update_crc_kermit */

 

    /*******************************************************************\
    *                                                                   *
    *   unsigned short update_crc_dnp( unsigned short crc, char c );    *
    *                                                                   *
    *   The function update_crc_dnp calculates a new CRC-DNP  value     *
    *   based  on  the  previous value of the CRC and the next byte     *
    *   of the data to be checked.                                      *
    *                                                                   *
    \*******************************************************************/

unsigned short update_crc_dnp( unsigned short crc, char c ) {

    unsigned short tmp, short_c;

    short_c = 0x00ff & (unsigned short) c;

    if ( ! crc_tabdnp_init ) init_crcdnp_tab();

    tmp =  crc       ^ short_c;
    crc = (crc >> 8) ^ crc_tabdnp[ tmp & 0xff ];

    return crc;

}  /* update_crc_dnp */

 

    /*******************************************************************\
    *                                                                   *
    *   unsigned long update_crc_32( unsigned long crc, char c );       *
    *                                                                   *
    *   The function update_crc_32 calculates a  new  CRC-32  value     *
    *   based  on  the  previous value of the CRC and the next byte     *
    *   of the data to be checked.                                      *
    *                                                                   *
    \*******************************************************************/

unsigned long update_crc_32( unsigned long crc, char c ) {

    unsigned long tmp, long_c;

    long_c = 0x000000ffL & (unsigned long) c;

    if ( ! crc_tab32_init ) init_crc32_tab();

    tmp = crc ^ long_c;
    crc = (crc >> 8) ^ crc_tab32[ tmp & 0xff ];

    return crc;

}  /* update_crc_32 */

 

    /*******************************************************************\
    *                                                                   *
    *   static void init_crc16_tab( void );                             *
    *                                                                   *
    *   The function init_crc16_tab() is used  to  fill  the  array     *
    *   for calculation of the CRC-16 with values.                      *
    *                                                                   *
    \*******************************************************************/

static void init_crc16_tab( void ) {

    int i, j;
    unsigned short crc, c;

    for (i=0; i<256; i++) {

        crc = 0;
        c   = (unsigned short) i;

        for (j=0; j<8; j++) {

            if ( (crc ^ c) & 0x0001 ) crc = ( crc >> 1 ) ^ P_16;
            else                      crc =   crc >> 1;

            c = c >> 1;
        }

        crc_tab16[i] = crc;
    }

    crc_tab16_init = TRUE;

}  /* init_crc16_tab */

 

    /*******************************************************************\
    *                                                                   *
    *   static void init_crckermit_tab( void );                         *
    *                                                                   *
    *   The function init_crckermit_tab() is used to fill the array     *
    *   for calculation of the CRC Kermit with values.                  *
    *                                                                   *
    \*******************************************************************/

static void init_crckermit_tab( void ) {

    int i, j;
    unsigned short crc, c;

    for (i=0; i<256; i++) {

        crc = 0;
        c   = (unsigned short) i;

        for (j=0; j<8; j++) {

            if ( (crc ^ c) & 0x0001 ) crc = ( crc >> 1 ) ^ P_KERMIT;
            else                      crc =   crc >> 1;

            c = c >> 1;
        }

        crc_tabkermit[i] = crc;
    }

    crc_tabkermit_init = TRUE;

}  /* init_crckermit_tab */

 

    /*******************************************************************\
    *                                                                   *
    *   static void init_crcdnp_tab( void );                            *
    *                                                                   *
    *   The function init_crcdnp_tab() is used  to  fill  the  array    *
    *   for calculation of the CRC-DNP with values.                     *
    *                                                                   *
    \*******************************************************************/

static void init_crcdnp_tab( void ) {

    int i, j;
    unsigned short crc, c;

    for (i=0; i<256; i++) {

        crc = 0;
        c   = (unsigned short) i;

        for (j=0; j<8; j++) {

            if ( (crc ^ c) & 0x0001 ) crc = ( crc >> 1 ) ^ P_DNP;
            else                      crc =   crc >> 1;

            c = c >> 1;
        }

        crc_tabdnp[i] = crc;
    }

    crc_tabdnp_init = TRUE;

}  /* init_crcdnp_tab */

 

    /*******************************************************************\
    *                                                                   *
    *   static void init_crc32_tab( void );                             *
    *                                                                   *
    *   The function init_crc32_tab() is used  to  fill  the  array     *
    *   for calculation of the CRC-32 with values.                      *
    *                                                                   *
    \*******************************************************************/

static void init_crc32_tab( void ) {

    int i, j;
    unsigned long crc;

    for (i=0; i<256; i++) {

        crc = (unsigned long) i;

        for (j=0; j<8; j++) {

            if ( crc & 0x00000001L ) crc = ( crc >> 1 ) ^ P_32;
            else                     crc =   crc >> 1;
        }

        crc_tab32[i] = crc;
    }

    crc_tab32_init = TRUE;

}  /* init_crc32_tab */

 

    /*******************************************************************\
    *                                                                   *
    *   static void init_crcccitt_tab( void );                          *
    *                                                                   *
    *   The function init_crcccitt_tab() is used to fill the  array     *
    *   for calculation of the CRC-CCITT with values.                   *
    *                                                                   *
    \*******************************************************************/

static void init_crcccitt_tab( void ) {

    int i, j;
    unsigned short crc, c;

    for (i=0; i<256; i++) {

        crc = 0;
        c   = ((unsigned short) i) << 8;

        for (j=0; j<8; j++) {

            if ( (crc ^ c) & 0x8000 ) crc = ( crc << 1 ) ^ P_CCITT;
            else                      crc =   crc << 1;

            c = c << 1;
        }

        crc_tabccitt[i] = crc;
    }

    crc_tabccitt_init = TRUE;

}  /* init_crcccitt_tab */

 

测试程序tst_crc.c

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "lib_crc.h"

 

    /*******************************************************************\
    *                                                                   *
    *   Library         : lib_crc                                       *
    *   File            : tst_crc.c                                     *
    *   Author          : Lammert Bies  1999-2008                       *
    *   E-mail          : info@lammertbies.nl                           *
    *   Language        : ANSI C                                        *
    *                                                                   *
    *                                                                   *
    *   Description                                                     *
    *   ===========                                                     *
    *                                                                   *
    *   The file tst_crc.c contains a small  sample  program  which     *
    *   demonstrates  the  use of the functions for calculating the     *
    *   CRC-CCITT, CRC-16 and CRC-32 values of data. The file  cal-     *
    *   culates  the three different CRC's for a file who's name is     *
    *   either provided at the command  line,  or  typed  in  right     *
    *   after the program has started.                                  *
    *                                                                   *
    *                                                                   *
    *   Dependencies                                                    *
    *   ============                                                    *
    *                                                                   *
    *   lib_crc.h       CRC definitions and prototypes                  *
    *   lib_crc.c       CRC routines                                    *
    *                                                                   *
    *                                                                   *
    *   Modification history                                            *
    *   ====================                                            *
    *                                                                   *
    *   Date        Version Comment                                     *
    *                                                                   *
    *   2008-04-20  1.16    Added CRC-CCITT calculation for Kermit.     *
    *                                                                   *
    *   2007-05-01  1.15    Added CRC16 calculation for Modbus.         *
    *                                                                   *
    *   2007-03-28  1.14    Added CRC16 routine for  Sick  devices,     *
    *                       electronic devices used for measurement     *
    *                       and detection in industrial situations.     *
    *                                                                   *
    *   2005-12-17  1.13    Added CRC-CCITT with initial 0x1D0F         *
    *                                                                   *
    *   2005-02-14  1.12    Added CRC-CCITT with initial 0x0000         *
    *                                                                   *
    *   2005-02-05  1.11    Fixed post processing bug in CRC-DNP.       *
    *                                                                   *
    *   2005-02-04  1.10    Added the CRC calculation for  DNP 3.0,     *
    *                       a protocol used  in  the  communication     *
    *                       between remote units and masters in the     *
    *                       electric utility industry.  The  method     *
    *                       of  calculation  is the same as CRC-16,     *
    *                       but with a different polynomial.            *
    *                                                                   *
    *   2005-01-07  1.02    Changed way program  is  used.  When  a     *
    *                       commandline  parameter  is present, the     *
    *                       program assumes it is a file, but  when     *
    *                       invoked without a parameter the entered     *
    *                       string is used to calculate the CRC.        *
    *                                                                   *
    *                       CRC's are now  printed  in  hexadecimal     *
    *                       decimal format.                             *
    *                                                                   *
    *                       Let  CRC-CCITT  calculation  start with     *
    *                       0xffff as this is used in  most  imple-     *
    *                       mentations.                                 *
    *                                                                   *
    *   1999-02-21  1.01    none                                        *
    *                                                                   *
    *   1999-01-22  1.00    Initial source                              *
    *                                                                   *
    \*******************************************************************/

#define MAX_STRING_SIZE 2048

 

void main( int argc, char *argv[] ) {

    char input_string[MAX_STRING_SIZE];
    char *ptr, *dest, hex_val, prev_byte;
    unsigned short crc_16, crc_16_modbus, crc_ccitt_ffff, crc_ccitt_0000, crc_ccitt_1d0f, crc_dnp, crc_sick, crc_kermit;
    unsigned short low_byte, high_byte;
    unsigned long crc_32;
    int a, ch, do_ascii, do_hex;
    FILE *fp;

    do_ascii = FALSE;
    do_hex   = FALSE;

    printf( "\nCRC algorithm sample program\nLammert Bies,  Version " CRC_VERSION "\n\n" );

    if ( argc < 2 ) {

        printf( "Usage: tst_crc [-a|-x] file1 ...\n\n" );
        printf( "    -a Program asks for ASCII input. Following parameters ignored.\n" );
        printf( "    -x Program asks for hexadecimal input. Following parameters ignored.\n" );
        printf( "       All other parameters are treated like filenames. The CRC values\n" );
        printf( "       for each separate file will be calculated.\n" );

        exit( 0 );
    }

    if ( ! strcmp( argv[1], "-a" )  ||  ! strcmp( argv[1], "-A" ) ) do_ascii = TRUE;
    if ( ! strcmp( argv[1], "-x" )  ||  ! strcmp( argv[1], "-X" ) ) do_hex   = TRUE;

    if ( do_ascii  ||  do_hex ) {

        printf( "Input: " );
        fgets( input_string, MAX_STRING_SIZE-1, stdin );
    }

    if ( do_ascii ) {

        ptr = input_string;
        while ( *ptr  &&  *ptr != '\r'  &&  *ptr != '\n' ) ptr++;
        *ptr = 0;
    }

    if ( do_hex ) {

        ptr  = input_string;
        dest = input_string;

        while( *ptr  &&  *ptr != '\r'  &&  *ptr != '\n' ) {

            if ( *ptr >= '0'  &&  *ptr <= '9' ) *dest++ = (char) ( (*ptr) - '0'      );
            if ( *ptr >= 'A'  &&  *ptr <= 'F' ) *dest++ = (char) ( (*ptr) - 'A' + 10 );
            if ( *ptr >= 'a'  &&  *ptr <= 'f' ) *dest++ = (char) ( (*ptr) - 'a' + 10 );

            ptr++;
 }

        * dest    = '\x80';
        *(dest+1) = '\x80';
    }

 

    a = 1;

    do {

        crc_16         = 0;
        crc_16_modbus  = 0xffff;
        crc_dnp        = 0;
        crc_sick       = 0;
        crc_ccitt_0000 = 0;
        crc_ccitt_ffff = 0xffff;
        crc_ccitt_1d0f = 0x1d0f;
        crc_kermit     = 0;
        crc_32         = 0xffffffffL;

 

        if ( do_ascii ) {

            prev_byte = 0;
            ptr       = input_string;

            while ( *ptr ) {

                crc_16         = update_crc_16(     crc_16,         *ptr            );
                crc_16_modbus  = update_crc_16(     crc_16_modbus,  *ptr            );
                crc_dnp        = update_crc_dnp(    crc_dnp,        *ptr            );
                crc_sick       = update_crc_sick(   crc_sick,       *ptr, prev_byte );
                crc_ccitt_0000 = update_crc_ccitt(  crc_ccitt_0000, *ptr            );
                crc_ccitt_ffff = update_crc_ccitt(  crc_ccitt_ffff, *ptr            );
                crc_ccitt_1d0f = update_crc_ccitt(  crc_ccitt_1d0f, *ptr            );
                crc_kermit     = update_crc_kermit( crc_kermit,     *ptr            );
                crc_32         = update_crc_32(     crc_32,         *ptr            );

                prev_byte = *ptr;
                ptr++;
            }
        }

 

        else if ( do_hex ) {

            prev_byte = 0;
            ptr       = input_string;

            while ( *ptr != '\x80' ) {

                hex_val  = (char) ( ( * ptr     &  '\x0f' ) << 4 );
                hex_val |= (char) ( ( *(ptr+1)  &  '\x0f' )      );

                crc_16         = update_crc_16(     crc_16,         hex_val            );
                crc_16_modbus  = update_crc_16(     crc_16_modbus,  hex_val            );
                crc_dnp        = update_crc_dnp(    crc_dnp,        hex_val            );
                crc_sick       = update_crc_sick(   crc_sick,       hex_val, prev_byte );
                crc_ccitt_0000 = update_crc_ccitt(  crc_ccitt_0000, hex_val            );
                crc_ccitt_ffff = update_crc_ccitt(  crc_ccitt_ffff, hex_val            );
                crc_ccitt_1d0f = update_crc_ccitt(  crc_ccitt_1d0f, hex_val            );
                crc_kermit     = update_crc_kermit( crc_kermit,     hex_val            );
                crc_32         = update_crc_32(     crc_32,         hex_val            );

                prev_byte = hex_val;
                ptr      += 2;
            }

            input_string[0] = 0;
        }

 

        else {

            prev_byte = 0;
            fp        = fopen( argv[a], "rb" );

            if ( fp != NULL ) {

                while( ( ch=fgetc( fp ) ) != EOF ) {

                    crc_16         = update_crc_16(     crc_16,         (char) ch            );
                    crc_16_modbus  = update_crc_16(     crc_16_modbus,  (char) ch            );
                    crc_dnp        = update_crc_dnp(    crc_dnp,        (char) ch            );
                    crc_sick       = update_crc_sick(   crc_sick,       (char) ch, prev_byte );
                    crc_ccitt_0000 = update_crc_ccitt(  crc_ccitt_0000, (char) ch            );
                    crc_ccitt_ffff = update_crc_ccitt(  crc_ccitt_ffff, (char) ch            );
                    crc_ccitt_1d0f = update_crc_ccitt(  crc_ccitt_1d0f, (char) ch            );
                    crc_kermit     = update_crc_kermit( crc_kermit,     (char) ch            );
                    crc_32         = update_crc_32(     crc_32,         (char) ch            );

                    prev_byte = (char) ch;
                }

                fclose( fp );
            }

            else printf( "%s : cannot open file\n", argv[a] );
        }

 

        crc_32    ^= 0xffffffffL;

        crc_dnp    = ~crc_dnp;
        low_byte   = (crc_dnp & 0xff00) >> 8;
        high_byte  = (crc_dnp & 0x00ff) << 8;
        crc_dnp    = low_byte | high_byte;

        low_byte   = (crc_sick & 0xff00) >> 8;
        high_byte  = (crc_sick & 0x00ff) << 8;
        crc_sick   = low_byte | high_byte;

        low_byte   = (crc_kermit & 0xff00) >> 8;
        high_byte  = (crc_kermit & 0x00ff) << 8;
        crc_kermit = low_byte | high_byte;

        printf( "%s%s%s :\nCRC16              = 0x%04X      /  %u\n"
                          "CRC16 (Modbus)     = 0x%04X      /  %u\n"
                          "CRC16 (Sick)       = 0x%04X      /  %u\n"
                          "CRC-CCITT (0x0000) = 0x%04X      /  %u\n"
                          "CRC-CCITT (0xffff) = 0x%04X      /  %u\n"
                          "CRC-CCITT (0x1d0f) = 0x%04X      /  %u\n"
                          "CRC-CCITT (Kermit) = 0x%04X      /  %u\n"
                          "CRC-DNP            = 0x%04X      /  %u\n"
                          "CRC32              = 0x%08lX  /  %lu\n"
                    , (   do_ascii  ||    do_hex ) ? "\""    : ""
                    , ( ! do_ascii  &&  ! do_hex ) ? argv[a] : input_string
                    , (   do_ascii  ||    do_hex ) ? "\""    : ""
                    , crc_16,         crc_16
                    , crc_16_modbus,  crc_16_modbus
                    , crc_sick,       crc_sick
                    , crc_ccitt_0000, crc_ccitt_0000
                    , crc_ccitt_ffff, crc_ccitt_ffff
                    , crc_ccitt_1d0f, crc_ccitt_1d0f
                    , crc_kermit,     crc_kermit
                    , crc_dnp,        crc_dnp
                    , crc_32,         crc_32     );

        a++;

    } while ( a < argc );

}  /* main (tst_crc.c) */

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值