#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Below from crc.h
#ifndef _crc_h
#define _crc_h
//El valor CHECK es el resultado de realizar el calculo CRC para el char[] = "123456789";
//The CHECK value is the result of making the checksum of the char[] = "123456789";
/*
* Valores sacados de la pagina http://c...content-available-to-author-only...e.net/crcmod.predefined.html Es posible que alguno este mal.
* This values have been taken from http://c...content-available-to-author-only...e.net/crcmod.predefined.html some of them could be wrong
Name Polynomial Reversed? Init-value XOR-out Check
crc-8 0x07 False 0x00 0x00 0xF4
crc-8-darc 0x39 True 0x00 0x00 0x15
crc-8-i-code 0x1D False 0xFD 0x00 0x7E
crc-8-itu 0x07 False 0x55 0x55 0xA1
crc-8-maxim 0x131 True 0x00 0x00 0xA1
crc-8-rohc 0x07 True 0xFF 0x00 0xD0
crc-8-wcdma 0x9B True 0x00 0x00 0x25
crc-16 0x8005 True 0x0000 0x0000 0xBB3D
crc-16-buypass 0x8005 False 0x0000 0x0000 0xFEE8
crc-16-dds-110 0x8005 False 0x800D 0x0000 0x9ECF
crc-16-dect 0x0589 False 0x0001 0x0001 0x007E
crc-16-dnp 0x3D65 True 0xFFFF 0xFFFF 0xEA82
crc-16-en-13757 0x3D65 False 0xFFFF 0xFFFF 0xC2B7
crc-16-genibus 0x1021 False 0x0000 0xFFFF 0xD64E
crc-16-maxim 0x8005 True 0xFFFF 0xFFFF 0x44C2
crc-16-mcrf4xx 0x1021 True 0xFFFF 0x0000 0x6F91
crc-16-riello 0x1021 True 0x554D 0x0000 0x63D0
crc-16-t10-dif 0x8BB7 False 0x0000 0x0000 0xD0DB
crc-16-teledisk 0xA097 False 0x0000 0x0000 0x0FB3
crc-16-usb 0x8005 True 0x0000 0xFFFF 0xB4C8
x-25 0x1021 True 0x0000 0xFFFF 0x906E
xmodem 0x1021 False 0x0000 0x0000 0x31C3
modbus 0x8005 True 0xFFFF 0x0000 0x4B37
kermit [1] 0x1021 True 0x0000 0x0000 0x2189
crc-ccitt-false [1] 0x1021 False 0xFFFF 0x0000 0x29B1
crc-aug-ccitt [1] 0x1021 False 0x1D0F 0x0000 0xE5CC
crc-24 0x864CFB False 0xB704CE 0x000000 0x21CF02
crc-24-flexray-a 0x5D6DCB False 0xFEDCBA 0x000000 0x7979BD
crc-24-flexray-b 0x5D6DCB False 0xABCDEF 0x000000 0x1F23B8
crc-32 0x04C11DB7 True 0x00000000 0xFFFFFFFF 0xCBF43926
crc-32-bzip2 0x04C11DB7 False 0xFFFFFFFF 0x00000000 0xFC891918
crc-32c 0x1EDC6F41 True 0x00000000 0xFFFFFFFF 0xE3069283
crc-32d 0xA833982B True 0x00000000 0xFFFFFFFF 0x87315576
crc-32-mpeg 0x04C11DB7 False 0xFFFFFFFF 0x00000000 0x0376E6E7
posix 0x04C11DB7 False 0xFFFFFFFF 0xFFFFFFFF 0x765E7680
crc-32q 0x814141AB False 0x00000000 0x00000000 0x3010BF7F
jamcrc 0x04C11DB7 True 0xFFFFFFFF 0x00000000 0x340BC6D9
xfer 0x000000AF False 0x00000000 0x00000000 0xBD0BE338
crc-64 0x000000000000001B True 0x0000000000000000 0x0000000000000000 0x46A5A9388A5BEFFE
crc-64-we 0x42F0E1EBA9EA3693 False 0x0000000000000000 0xFFFFFFFFFFFFFFFF 0x62EC59E3F1A4F00A
crc-64-jones 0xAD93D23594C935A9 True 0xFFFFFFFFFFFFFFFF 0x0000000000000000 0xCAA717168609F281
*/
#include <stdint.h>
#define TRUE 1
#define FALSE 0
//Indicate here the CRC algorithm that you want to use
#define CRC_32
//Indicate here if you want to do the calculation using a LookupTable
#define CALCULATE_LOOKUPTABLE TRUE
#if defined(CRC_8)
typedef uint8_t crc;
#define POLYNOMIAL 0x07
#define INITIAL_VALUE 0
#define FINAL_XOR_VALUE 0
#define REVERSED_DATA FALSE
#define REVERSED_OUT FALSE
#elif defined(CRC_CCITT)
typedef uint16_t crc;
#define POLYNOMIAL 0x1021
#define INITIAL_VALUE 0xFFFF
#define FINAL_XOR_VALUE 0
#define REVERSED_DATA FALSE
#define REVERSED_OUT FALSE
#elif defined(MODBUS)
typedef uint16_t crc;
#define POLYNOMIAL 0x8005
#define INITIAL_VALUE 0xFFFF
#define FINAL_XOR_VALUE 0
#define REVERSED_DATA TRUE
#define REVERSED_OUT FALSE
#elif defined(CRC_16)
typedef uint16_t crc;
#define POLYNOMIAL 0x8005
#define INITIAL_VALUE 0x0000
#define FINAL_XOR_VALUE 0x0000
#define REVERSED_DATA TRUE
#define REVERSED_OUT FALSE
#elif defined(CRC_24)
//Since is impossible to define a 24bit variable and i need to use and structure instead, what i have done is just put the WIDTH directly. In this case the valid part from the result,
//will be the less significat 24bits (&0xFFF) the rest must be discarted.
//Como es imposible definir variables de 24bits y necesito crear una estructura, lo que he hecho es definir la anchura directamente para poder conseguir un resultado valido.
//Para este caso la parte con la que debemos quedarnos son los 24 bits de menos peso (&0xFFF), la parte alta debemos de descartarla
typedef uint32_t crc;
#define POLYNOMIAL 0x864CFB
#define INITIAL_VALUE 0xB704CE
#define FINAL_XOR_VALUE 0x000000
#define REVERSED_DATA FALSE
#define REVERSED_OUT FALSE
#define WIDTH (24)
#elif defined(CRC_32)
typedef uint32_t crc;
#define POLYNOMIAL 0x04C11DB7
#define INITIAL_VALUE 0xFFFFFFFF
#define FINAL_XOR_VALUE 0xFFFFFFFF
#define REVERSED_DATA TRUE
#define REVERSED_OUT FALSE
#elif defined(CRC_32_BZIP2)
typedef uint32_t crc;
#define POLYNOMIAL 0x04C11DB7
#define INITIAL_VALUE 0xFFFFFFFF
#define FINAL_XOR_VALUE 0
#define REVERSED_DATA FALSE
#define REVERSED_OUT TRUE
#elif defined(CRC_64_JONES)
typedef uint64_t crc;
#define POLYNOMIAL 0xAD93D23594C935A9
#define INITIAL_VALUE 0xFFFFFFFFFFFFFFFF
#define FINAL_XOR_VALUE 0
#define REVERSED_DATA TRUE
#define REVERSED_OUT FALSE
#else
#error "Debes definir un algoritmo CRC"
#error "You should define at least one algorithm"
#endif
#if (CALCULATE_LOOKUPTABLE == FALSE)
#define F_CRC_InicializaTabla()
#else
void F_CRC_InicializaTabla(void);
#endif
crc F_CRC_CalculaCheckSum(uint8_t const AF_Datos[], uint16_t VF_nBytes);
#endif
// crc.c below
/*
* Derive parameters from the standard-specific parameters in crc.h.
*/
#ifndef WIDTH
#define WIDTH (8 * sizeof(crc))
#endif
#define TOPBIT (((crc)1) << (WIDTH - 1))
#if (REVERSED_DATA == TRUE)
#define FP_reflect_DATA(_DATO) ((uint8_t)(FP_reflect((_DATO), 8)&0xFF))
#define FP_reflect_CRCTableValue(_CRCTableValue) ((crc) FP_reflect((_CRCTableValue), WIDTH))
#else
#define FP_reflect_DATA(_DATO) (_DATO)
#define FP_reflect_CRCTableValue(_CRCTableValue) (_CRCTableValue)
#endif
#if (CALCULATE_LOOKUPTABLE == TRUE)
static crc A_crcLookupTable[256] = {0};
#endif
/*********************************************************************
*
* Function: FP_reflect()
*
* Description: A value/register is reflected if it's bits are swapped around its centre.
* For example: 0101 is the 4-bit reflection of 1010
*
* Descripción: Un valor es reflejado cuando sus bits son intercambiados utilizando como punto de referencia el centro.
* Por ejemplo: 0101 es el reflejo de 1010
*
*********************************************************************/
#if (REVERSED_DATA == TRUE)
static crc FP_reflect(crc VF_dato, uint8_t VF_nBits)
{
crc VP_reflection = 0;
uint8_t VP_Pos_bit = 0;
for (VP_Pos_bit = 0; VP_Pos_bit < VF_nBits; VP_Pos_bit++)
{
if ((VF_dato & 1) == 1)
{
VP_reflection |= (((crc)1) << ((VF_nBits - 1) - VP_Pos_bit));
}
VF_dato = (VF_dato >> 1);
}
return (VP_reflection);
}
#endif
/*********************************************************************
*
* Function: F_CRC_ObtenValorDeTabla()
*
* Description: Obtains the Table value
* Descripción: Obtiene el valor de la tabla
*
*
*********************************************************************/
static crc F_CRC_ObtenValorDeTabla(uint8_t VP_Pos_Tabla)
{
crc VP_CRCTableValue = 0;
uint8_t VP_Pos_bit = 0;
VP_CRCTableValue = ((crc) FP_reflect_DATA(VP_Pos_Tabla)) << (WIDTH - 8);
for (VP_Pos_bit = 0; VP_Pos_bit < 8; VP_Pos_bit++)
{
if (VP_CRCTableValue & TOPBIT)
{
VP_CRCTableValue = (VP_CRCTableValue << 1) ^ POLYNOMIAL;
}
else
{
VP_CRCTableValue = (VP_CRCTableValue << 1);
}
}
return (FP_reflect_CRCTableValue(VP_CRCTableValue));
}
#if (CALCULATE_LOOKUPTABLE == TRUE)
/*********************************************************************
*
* Function: F_CRC_InicializaTabla()
*
* Description: Create the lookup table for the CRC
* Descripción: Crea la tabla de lookup para el computo del CRC
*
*
*********************************************************************/
void F_CRC_InicializaTabla(void)
{
uint16_t VP_Pos_Array = 0;
for (VP_Pos_Array = 0; VP_Pos_Array < 256; VP_Pos_Array++)
{
A_crcLookupTable[VP_Pos_Array] = F_CRC_ObtenValorDeTabla((uint8_t)(VP_Pos_Array &0xFF));
}
}
/*********************************************************************
*
* Function: F_CRC_CalculaCheckSumDeTabla()
*
* Description: Calculate the CRC value from a Lookup Table.
*
* Notes: F_CRC_InicializaTabla() must be called first.
* Since AF_Datos is a char array, it is possible to compute any kind of file or array.
* Notes: F_CRC_InicializaTabla() debe ser llamado primero
* Como AF_Datos es un array de char, tiene capacidad para calcular la checksum de cualquier fichero o array.
*
* Returns: The CRC of the AF_Datos.
* Retorna: El computo del CRC
*
*********************************************************************/
crc F_CRC_CalculaCheckSum(uint8_t const AF_Datos[], uint16_t VF_nBytes)
{
crc VP_CRCTableValue = INITIAL_VALUE;
uint16_t VP_bytes = 0;
for (VP_bytes = 0; VP_bytes < VF_nBytes; VP_bytes++)
{
#if (REVERSED_DATA == TRUE)
VP_CRCTableValue = (VP_CRCTableValue >> 8) ^ A_crcLookupTable[((uint8_t)(VP_CRCTableValue & 0xFF)) ^ AF_Datos[VP_bytes]];
#else
VP_CRCTableValue = (VP_CRCTableValue << 8) ^ A_crcLookupTable[((uint8_t)((VP_CRCTableValue >> (WIDTH - 8)) & 0xFF)) ^ AF_Datos[VP_bytes]];
#endif
}
if ((8 * sizeof(crc)) > WIDTH)
{
VP_CRCTableValue = VP_CRCTableValue & ((((crc)(1)) << WIDTH) - 1);
}
#if (REVERSED_OUT == FALSE)
return (VP_CRCTableValue ^ FINAL_XOR_VALUE);
#else
return (~VP_CRCTableValue ^ FINAL_XOR_VALUE);
#endif
}
#else
/*********************************************************************
*
* Function: F_CRC_CalculaCheckSumSinTabla()
*
* Description: Calculate the CRC value withouth a lookup table
* Description: Calculate el CRC sin tabla de lookup
*
* Notes:
*
* Returns: The CRC of the AF_Datos.
* Retorna: El computo de CRC de AF_DAtos
*
*********************************************************************/
crc F_CRC_CalculaCheckSum(uint8_t const AF_Datos[], int16_t VF_nBytes)
{
crc VP_CRCTableValue = INITIAL_VALUE;
int16_t VP_bytes = 0;
for (VP_bytes = 0; VP_bytes < VF_nBytes; VP_bytes++)
{
#if (REVERSED_DATA == TRUE)
VP_CRCTableValue = (VP_CRCTableValue >> 8) ^ F_CRC_ObtenValorDeTabla(((uint8_t)(VP_CRCTableValue & 0xFF)) ^ AF_Datos[VP_bytes]);
#else
VP_CRCTableValue = (VP_CRCTableValue << 8) ^ F_CRC_ObtenValorDeTabla(((uint8_t)((VP_CRCTableValue >> (WIDTH - 8)) & 0xFF)) ^ AF_Datos[VP_bytes]);
#endif
}
if ((8 * sizeof(crc)) > WIDTH)
{
VP_CRCTableValue = VP_CRCTableValue & ((((crc)(1)) << WIDTH) - 1);
}
#if (REVERSED_OUT == FALSE)
return (VP_CRCTableValue ^ FINAL_XOR_VALUE);
#else
return (~VP_CRCTableValue ^ FINAL_XOR_VALUE);
#endif
}
#endif
// main.c below
// Put all include at the top of this "file", except crc.h
int main()
{
int8_t A_Texto[124]; // PAS: Changed from 40
crc CRC_Result = 0;
printf("CRC32 calculator\r\n"); printf("For other CRCs change #define CRC_32 value in the crc.h file\r\n"); printf("Insert value and press enter:");
fgets(A_Texto
, 124, stdin
); // PAS: Changed from 40
F_CRC_InicializaTabla();
CRC_Result
= F_CRC_CalculaCheckSum
(A_Texto
, strlen(A_Texto
)-1); printf("Result: 0x%X", CRC_Result
); return 0;
}