CRC32 几个参数 附带源码

标准 CRC32 参数如下:

CRC在线计算 (lddgo.net)

非标准 CRC32:

多项式的值:0x04C11DB7 ,

初始值:0xFFFFFFFF,

结果异或值: 0x0,

数据输入反转 关闭,

数据输出反转 关闭。

 源码是非标准CRC32,  可以更改里面的参数 变成 标准 CRC32;

/**********************************************************************
 *
 * Filename:    crc32.c
 *
 * Description: Slow and fast implementations of the CRC32 standards.
 *
 * Notes:       The parameters for each supported CRC standard are
 *                defined in the header file crc.h.  The implementations
 *                here should stand up to further additions to that 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.
 **********************************************************************/

/**
 * @file    crc32.c
 * @brief   Implementation of crc32.h
 */

#include "crc32.h"

#define FALSE    0
#define TRUE    !FALSE

typedef unsigned long  crc;

#define CRC_NAME                     "CRC-32"

// 多项式
#define POLYNOMIAL                0x04C11DB7
//#define POLYNOMIAL                0xEDB88320
//#define POLYNOMIAL                0xDB710641
//#define POLYNOMIAL                0x82608ED8

// 初始值
#define INITIAL_REMAINDER    0xFFFFFFFF

// 结果异或值
#define FINAL_XOR_VALUE        0x0UL

// 输入反转 关闭
#define REFLECT_DATA          FALSE
// 输出反转 关闭
#define REFLECT_REMAINDER    FALSE


/*
 * Derive parameters from the standard-specific parameters in crc32.h.
 */
#define WIDTH    (8 * sizeof(crc))
#define TOPBIT   (1U << (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:    crc32()
 *
 * Description: Compute the CRC of a given message.
 *
 * Notes:
 *
 * Returns:        The CRC of the message.
 *
 *********************************************************************/
uint32_t crc32(const void *data, int nBytes)
{
    crc            remainder = INITIAL_REMAINDER;
    int            byte;
    unsigned char  bit;
    unsigned char const *message = data;

    /*
     * 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);
}   /* crc32() */

/*********************************************************************
 *
 * Function:    crc32_continue()
 *
 * Description: Compute the CRC of a given message.
 *
 * Notes:
 *
 * Returns:        The CRC of the message.
 *
 *********************************************************************/
uint32_t crc32_continue(uint32_t prev_crc, const void *data, int nBytes)
{
    crc            remainder = REFLECT_REMAINDER(prev_crc ^ FINAL_XOR_VALUE);
    int            byte;
    unsigned char  bit;
    unsigned char const *message = data;

    /*
     * 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);
}   /* crc32_continue() */

/**************************************************************************************************
 * @fn          crc16
 *
 * @brief       Run the CRC16 Polynomial calculation over the byte parameter.
 *
 * input parameters
 *
 * @param       crc - Running CRC calculated so far.
 * @param       val - Value on which to run the CRC16.
 *
 * output parameters
 *
 * None.
 *
 * @return      crc - Updated for the run.
 **************************************************************************************************
 */
uint16_t crc16(uint16_t crc, uint8_t val)
{
  const uint16_t poly = 0x1021;
  uint8_t cnt;

  for (cnt = 0; cnt < 8; cnt++, val <<= 1)
  {
    uint8_t msb = (crc & 0x8000) ? 1 : 0;

    crc <<= 1;
    if (val & 0x80)  crc |= 0x0001;
    if (msb)         crc ^= poly;
  }

  return crc;
}
/**********************************************************************
 *
 * 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.
 **********************************************************************/

/**
 * @file    crc.h
 * @brief   CRC functions
 */

#ifndef _crc_h
#define _crc_h

#include "stdint.h"

#ifdef __cplusplus
extern "C" {
#endif

uint32_t crc32(const void *data, int nBytes);
uint32_t crc32_continue(uint32_t prev_crc, const void *data, int nBytes);
uint16_t crc16(uint16_t crc, uint8_t val);

#ifdef __cplusplus
}
#endif

#endif
原文地址:https://www.cnblogs.com/suozhang/p/15789208.html