1. 程式人生 > 其它 >CRC32 幾個引數 附帶原始碼

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