www.pudn.com > 文件恢复及修补 C 语言源程序.zip > CRC.C


 
/****************************************************************************** 
*                                                                             * 
*               Cyclic Redundancy Check (CRC) functions                       * 
*                                                                             * 
******************************************************************************/ 
 
/* 
*   crc_clear: 
*       This function clears the CRC to zero. It should be called prior to 
*       the start of the processing of a block for both received messages, 
*       and messages to be transmitted. 
* 
*       Calling sequence: 
* 
*       short crc; 
*       crc = crc_clear(); 
*/ 
short crc_clear() 
{ 
        return(0); 
} 
/* 
*   crc_update: 
*       this function must be called once for each character which is 
*       to be included in the CRC for messages to be transmitted. 
*       This function is called once for each character which is included 
*       in the CRC of a received message, AND once for each of the two CRC 
*       characters at the end of the received message. If the resulting 
*       CRC is zero, then the message has been correctly received. 
* 
*   Calling sequence: 
* 
*       crc = crc_update(crc,next_char); 
*/ 
short crc_update(crc,crc_char) 
short crc; 
char crc_char; 
{ 
        long x; 
        short i; 
 
/* "x" will contain the character to be processed in bits 0-7 and the CRC    */ 
/* in bits 8-23. Bit 24 will be used to test for overflow, and then cleared  */ 
/* to prevent the sign bit of "x" from being set to 1. Bits 25-31 are not    */ 
/* used. ("x" is treated as though it is a 32 bit register).                 */ 
        x = ((long)crc << 8) + crc_char;    /* Get the CRC and the character */ 
 
/* Repeat the following loop 8 times (for the 8 bits of the character).      */ 
        for(i = 0;i < 8;i++) 
        { 
 
/* Shift the high-order bit of the character into the low-order bit of the   */ 
/* CRC, and shift the high-order bit of the CRC into bit 24.                 */ 
                x = x << 1;                        /* Shift "x" left one bit */ 
 
/* Test to see if the old high-order bit of the CRC was a 1.                 */ 
                if(x & 0x01000000)                     /* Test bit 24 of "x" */ 
 
/* If the old high-order bit of the CRC was a 1, exclusive-or it with a one  */ 
/* to set it to 0, and exclusive-or the CRC with hex 1021 to produce the     */ 
/* CCITT-recommended CRC generator of: X**16 + X**12 + X**5 + 1. To produce  */ 
/* the CRC generator of: X**16 + X**15 + X**2 + 1, change the constant from  */ 
/* 0x01102100 to 0x01800500. This will exclusive-or the CRC with hex 8005    */ 
/* and produce the same CRC that IBM uses for their synchronous transmission */ 
/* protocols.                                                                */ 
                        x = x ^ 0x01102100;     /* Exclusive-or "x" with a...*/ 
                                              /* ...constant of hex 01102100 */ 
/* And repeat 8 times.                                                       */ 
        }                                               /* End of "for" loop */ 
 
/* Return the CRC as the 16 low-order bits of this function's value.         */ 
        return(((x & 0x00ffff00) >> 8)); /* AND off the unneeded bits and... */ 
                                  /* ...shift the result 8 bits to the right */ 
 
} 
/* 
*   crc_finish: 
*       This function must be called once after all the characters in a block 
*       have been processed for a message which is to be TRANSMITTED. It 
*       returns the calculated CRC bytes, which should be transmitted as the 
*       two characters following the block. The first of these 2 bytes 
*       must be taken from the high-order byte of the CRC, and the second 
*       must be taken from the low-order byte of the CRC. This routine is NOT 
*       called for a message which has been RECEIVED. 
* 
*   Calling sequence: 
* 
*       crc = crc_finish(crc); 
*/ 
short crc_finish(crc) 
short crc; 
{ 
/* Call crc_update twice, passing it a character of hex 00 each time, to     */ 
/* flush out the last 16 bits from the CRC calculation, and return the       */ 
/* result as the value of this function.                                     */ 
        return(crc_update(crc_update(crc,'\0'),'\0')); 
 
} 
 
/* 
* This is a sample of the use of the CRC functions, which calculates the 
* CRC for a 1-character message block, and then passes the resulting CRC back 
* into the CRC functions to see if the "received" 1-character message and CRC 
* are correct. 
*/ 
main() 
{ 
 
        short crc;                                     /* The calculated CRC */ 
        char crc_char;                            /* The 1-character message */ 
        char x, y;            /* 2 places to hold the 2 "received" CRC bytes */ 
 
        crc_char = 'A';                    /* Define the 1-character message */ 
        crc = crc_clear();      /* Reset the CRC to "transmit" a new message */ 
        crc = crc_update(crc,crc_char);   /* Update the CRC for the first... */ 
                                   /* ...(and only) character of the message */ 
        crc = crc_finish(crc);        /* Finish the transmission calculation */ 
        x = (char)((crc & 0xff00) >> 8);  /* Extract the high-order CRC byte */ 
        y = (char)(crc & 0x00ff);          /* And extract the low-order byte */ 
        printf("%04x\n",crc);                           /* Print the results */ 
 
        crc = crc_clear();                 /* Prepare to "receive" a message */ 
        crc = crc_update(crc,crc_char);   /* Update the CRC for the first... */ 
                                   /* ...(and only) character of the message */ 
        crc = crc_update(crc,x);     /* Pass both bytes of the "received"... */ 
        crc = crc_update(crc,y);           /* ...CRC through crc_update, too */ 
        printf("%04x\n",crc);    /* If the result was 0, then the message... */ 
                                            /* ...was received without error */ 
 
}