zoukankan      html  css  js  c++  java
  • CRC循环校验的具体算法(转)

    /**********************************************************************
    *
    * Filename: main.c
    *
    * Description: A simple test program for the CRC implementations.
    *
    * Notes: To test a different CRC standard, modify crc.h.
    *
    *
    * Copyright (c) 2000 by Michael Barr. This software is placed into
    * the public domain and may be used for any purpose. However, this
    * notice must not be changed or removed and no warranty is either
    * expressed or implied by its publication or distribution.
    **********************************************************************/


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

    #include "crc.h"


    void
    main(void)
    {
    unsigned char test[] = "123456789";


    /*
    * Print the check value for the selected CRC algorithm.
    */
    printf("The check value for the %s standard is 0x%X\n", CRC_NAME,
    CHECK_VALUE);

    /*
    * Compute the CRC of the test message, slowly.
    */
    */
    printf("The crcSlow() of \"123456789\" is 0x%X\n", crcSlow(test,
    strlen(test)));

    /*
    * Compute the CRC of the test message, more efficiently.
    */
    crcInit();
    printf("The crcFast() of \"123456789\" is 0x%X\n", crcFast(test,
    strlen(test)));

    } /* main() */

    /**********************************************************************
    *
    * Filename: crc.h
    *
    * Description: A header file describing the various CRC standards.
    *
    * Notes:
    *
    *
    * Copyright (c) 2000 by Michael Barr. This software is placed into

    * the public domain and may be used for any purpose. However, this
    * notice must not be changed or removed and no warranty is either
    * expressed or implied by its publication or distribution.
    **********************************************************************/

    #ifndef _crc_h
    #define _crc_h


    #define FALSE 0
    #define TRUE !FALSE

    /*
    * Select the CRC standard from the list that follows.
    */
    #define CRC_CCITT


    #if defined(CRC_CCITT)

    typedef unsigned short crc;


    #define CRC_NAME "CRC-CCITT"
    #define POLYNOMIAL 0x1021
    #define INITIAL_REMAINDER 0xFFFF
    #define FINAL_XOR_VALUE 0x0000
    #define REFLECT_DATA FALSE
    #define REFLECT_REMAINDER FALSE
    #define CHECK_VALUE 0x29B1

    #elif defined(CRC16)

    typedef unsigned short crc;

    #define CRC_NAME "CRC-16"
    #define POLYNOMIAL 0x8005
    #define INITIAL_REMAINDER 0x0000
    #define FINAL_XOR_VALUE 0x0000
    #define REFLECT_DATA TRUE
    #define REFLECT_REMAINDER TRUE
    #define CHECK_VALUE 0xBB3D

    #elif defined(CRC32)


    typedef unsigned long crc;

    #define CRC_NAME "CRC-32"
    #define POLYNOMIAL 0x04C11DB7
    #define INITIAL_REMAINDER 0xFFFFFFFF
    #define FINAL_XOR_VALUE 0xFFFFFFFF
    #define REFLECT_DATA TRUE
    #define REFLECT_REMAINDER TRUE
    #define CHECK_VALUE 0xCBF43926

    #else

    #error "One of CRC_CCITT, CRC16, or CRC32 must be #define'd."

    #endif


    void crcInit(void);
    crc crcSlow(unsigned char const message[], int nBytes);
    crc crcFast(unsigned char const message[], int nBytes);



    #endif /* _crc_h */



    /**********************************************************************
    *
    * Filename: crc.c
    *
    * Description: Slow and fast implementations of the CRC standards.
    *
    * Notes: The parameters for each supported CRC standard are
    * defined in the header file crc.h. The implementtations
    * here should stand up to further additions to thaat list.
    *
    *
    * Copyright (c) 2000 by Michael Barr. This software is placed into
    * the public domain and may be used for any purpose. However, this
    * notice must not be changed or removed and no warranty is either
    * expressed or implied by its publication or distribution.
    **********************************************************************/

    #include "crc.h"
    #include "crc.h"


    /*
    * Derive parameters from the standard-specific parameters in crc.h.
    */
    #define WIDTH (8 * sizeof(crc))
    #define TOPBIT (1 << (WIDTH - 1))

    #if (REFLECT_DATA == TRUE)
    #undef REFLECT_DATA
    #define REFLECT_DATA(X) ((unsigned char) reflect((X), 8))
    #else
    #undef REFLECT_DATA
    #define REFLECT_DATA(X) (X)
    #endif

    #if (REFLECT_REMAINDER == TRUE)
    #undef REFLECT_REMAINDER
    #define REFLECT_REMAINDER(X) ((crc) reflect((X), WIDTH))
    #else
    #undef REFLECT_REMAINDER
    #define REFLECT_REMAINDER(X) (X)

    #endif


    /*********************************************************************
    *
    * Function: reflect()
    *
    * Description: Reorder the bits of a binary sequence, by reflecting
    * them about the middle position.
    *
    * Notes: No checking is done that nBits <= 32.
    *
    * Returns: The reflection of the original data.
    *
    *********************************************************************/
    static unsigned long
    reflect(unsigned long data, unsigned char nBits)
    {
    unsigned long reflection = 0x00000000;
    unsigned char bit;

    /*
    /*
    * Reflect the data about the center bit.
    */
    for (bit = 0; bit < nBits; ++bit)
    {
    /*
    * If the LSB bit is set, set the reflection of it.
    */
    if (data & 0x01)
    {
    reflection |= (1 << ((nBits - 1) - bit));
    }

    data = (data >> 1);
    }

    return (reflection);

    } /* reflect() */


    /*********************************************************************
    *
    *
    * Function: crcSlow()
    *
    * Description: Compute the CRC of a given message.
    *
    * Notes:
    *
    * Returns: The CRC of the message.
    *
    *********************************************************************/
    crc
    crcSlow(unsigned char const message[], int nBytes)
    {
    crc remainder = INITIAL_REMAINDER;
    int byte;
    unsigned char bit;


    /*
    * Perform modulo-2 division, a byte at a time.
    */
    for (byte = 0; byte < nBytes; ++byte)
    {
    {
    /*
    * Bring the next byte into the remainder.
    */
    remainder ^= (REFLECT_DATA(message[byte]) << (WIDTH - 8));

    /*
    * Perform modulo-2 division, a bit at a time.
    */
    for (bit = 8; bit > 0; --bit)
    {
    /*
    * Try to divide the current data bit.
    */
    if (remainder & TOPBIT)
    {
    remainder = (remainder << 1) ^ POLYNOMIAL;
    }
    else
    {
    remainder = (remainder << 1);
    }
    }
    }
    }

    /*
    * The final remainder is the CRC result.
    */
    return (REFLECT_REMAINDER(remainder) ^ FINAL_XOR_VALUE);

    } /* crcSlow() */


    crc crcTable[256];


    /*********************************************************************
    *
    * Function: crcInit()
    *
    * Description: Populate the partial CRC lookup table.
    *
    * Notes: This function must be rerun any time the CRC standard
    * is changed. If desired, it can be run "offline"" and
    * the table results stored in an embedded system'ss ROM.

    *
    * Returns: None defined.
    *
    *********************************************************************/
    void
    crcInit(void)
    {
    crc remainder;
    int dividend;
    unsigned char bit;


    /*
    * Compute the remainder of each possible dividend.
    */
    for (dividend = 0; dividend < 256; ++dividend)
    {
    /*
    * Start with the dividend followed by zeros.
    */
    remainder = dividend << (WIDTH - 8);


    /*
    * Perform modulo-2 division, a bit at a time.
    */
    for (bit = 8; bit > 0; --bit)
    {
    /*
    * Try to divide the current data bit.
    */
    if (remainder & TOPBIT)
    {
    remainder = (remainder << 1) ^ POLYNOMIAL;
    }
    else
    {
    remainder = (remainder << 1);
    }
    }

    /*
    * Store the result into the table.
    */
    crcTable[dividend] = remainder;

    }

    } /* crcInit() */


    /*********************************************************************
    *
    * Function: crcFast()
    *
    * Description: Compute the CRC of a given message.
    *
    * Notes: crcInit() must be called first.
    *
    * Returns: The CRC of the message.
    *
    *********************************************************************/
    crc
    crcFast(unsigned char const message[], int nBytes)
    {
    crc remainder = INITIAL_REMAINDER;
    unsigned char data;
    int byte;
    int byte;


    /*
    * Divide the message by the polynomial, a byte at a time.
    */
    for (byte = 0; byte < nBytes; ++byte)
    {
    data = REFLECT_DATA(message[byte]) ^ (remainder >> (WIDTH - 8));
    remainder = crcTable[data] ^ (remainder << 8);
    }

    /*
    * The final remainder is the CRC.
    */
    return (REFLECT_REMAINDER(remainder) ^ FINAL_XOR_VALUE);

    } /* crcFast() */
  • 相关阅读:
    js取当前时间的秒级时间戳
    微信自动聊天脚本
    小程序 缓存过期问题
    去掉表格默认样式
    css3 画心
    数据导入(二):MapReduce
    数据导入(一):Hive On HBase
    HBase参数优化
    Hadoop运维手记
    HBase优化相关
  • 原文地址:https://www.cnblogs.com/zhuor/p/306440.html
Copyright © 2011-2022 走看看