ccrc

How can I find CRC from this data


The CRC value of the incoming data is the 23rd data value, and I need to generate this CRC value. However, I've tried using CRC-8, LRC, BCC, and checksum methods, but they all yield different results. I don't know what to add or modify to create the CRC value in the 23rd data. I really need help with this.

I have tried using CRC, LRC, checksum, and BCC with the below code. The values comments are the checksum values.

#include <stdio.h>

unsigned char a[19][22] =
{
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04}, //ad  (checksum value)
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04}, //ad
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04}, //ad
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x00,0x04}, //b2
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x09,0x19,0x53,0x00,0x11,0x20,0x45,0x02,0x91}, //e1
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x29,0x20,0x43,0x00,0x11,0x20,0x46,0x03,0x01}, //d3
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x38,0x20,0x83,0x00,0x11,0x20,0x47,0x03,0x21}, //da
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x43,0x21,0x13,0x00,0x11,0x20,0x47,0x03,0x21}, //d0
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x47,0x21,0x23,0x00,0x11,0x20,0x47,0x03,0x21}, //d5
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x49,0x21,0x33,0x00,0x11,0x00,0x48,0x03,0x21}, //d7
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x51,0x21,0x43,0x00,0x11,0x00,0x48,0x03,0x21}, //d1
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x52,0x21,0x53,0x00,0x11,0x30,0x48,0x03,0x21}, //d6
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x52,0x21,0x63,0x00,0x11,0x20,0x48,0x03,0x31}, //d7
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x52,0x21,0x63,0x00,0x11,0x00,0x48,0x03,0x31}, //d5
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x53,0x21,0x53,0x00,0x11,0x20,0x48,0x03,0x21}, //d6
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x53,0x21,0x53,0x00,0x11,0x20,0x48,0x03,0x21}, //d6
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x53,0x21,0x53,0x00,0x11,0x30,0x48,0x03,0x21}, //d7
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x53,0x21,0x53,0x00,0x11,0x20,0x48,0x03,0x21}, //d6
{0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x53,0x21,0x53,0x00,0x11,0x00,0x48,0x03,0x21}  //d4
}; 


unsigned char calculate_byte_sum(unsigned char *data, int length)
{
    unsigned char checksum = 0;
    int i;

    for (i = 0; i< length; i++) 
    {
        checksum += data[i];
    }
    return checksum;
}

unsigned char calculate_crc8(unsigned char *data, int length) 
{
    unsigned char crc = 0x00; 
    unsigned char polynomial = 0x07;

    for (int i = 0; i < length; i++) 
    {
        crc += data[i];
        for (int j = 0; j < 8; j++) 
        {
            if (crc & 0x80) 
            {
                crc = (crc << 1) ^ polynomial;
            } 
            else
            {
                crc <<= 1;
            }
        }
    }
    return crc;
}


unsigned char calculate_bcc(unsigned char *data, int length)
{
    unsigned char bcc = 0;
    for (int i = 0; i < length; i++) 
    {
        bcc ^= data[i];
    }
    return bcc;
}

unsigned char calculate_lrc(unsigned char *data, int length) 
{
    unsigned char lrc = 0;
    for (int i = 0; i < length; i++) 
    {
        lrc += data[i];
    }
    return (unsigned char)((~lrc));
}


void fcs_test(unsigned char* data, unsigned int len) 
{
    unsigned char ch,ch1, ch2,ch3,ch4,ch5;
    ch = calculate_byte_sum(data, len);
    ch1 = calculate_crc8(data, len);
    ch2 = calculate_bcc(data,len);
    ch3= calculate_lrc(data,len);

    printf("calculate_byte_sum = %02x     calculate_crc8 = %02x    calculate_bcc = %02x    calculate_lrc = %02x\n", ch,ch1,ch2,ch3);
//    printf("fcs = %02x \n", ch);
}


int main()
{
    unsigned int  i;
    for (i=0 ; i < 19; i++)
    {
        fcs_test(&a[i][0], 22);
    }
    return 0;
}

Solution

  • Based on some observations described in Martin Brown's comments above, this may be simply a sum of nibbles, with some additional constant, like this (try it out on Godbolt as well):

    #include <stdio.h>
    
    #define NUM_ROWS 19
    #define NUM_COLS 22
    
    unsigned char arr[NUM_ROWS][NUM_COLS] =
    {
    {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04}, // ad
    {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04}, // ad
    {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04}, // ad
    {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x00,0x04}, // b2
    {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x09,0x19,0x53,0x00,0x11,0x20,0x45,0x02,0x91}, // e1
    {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x29,0x20,0x43,0x00,0x11,0x20,0x46,0x03,0x01}, // d3
    {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x38,0x20,0x83,0x00,0x11,0x20,0x47,0x03,0x21}, // da
    {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x43,0x21,0x13,0x00,0x11,0x20,0x47,0x03,0x21}, // d0
    {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x47,0x21,0x23,0x00,0x11,0x20,0x47,0x03,0x21}, // d5
    {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x49,0x21,0x33,0x00,0x11,0x00,0x48,0x03,0x21}, // d7
    {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x51,0x21,0x43,0x00,0x11,0x00,0x48,0x03,0x21}, // d1
    {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x52,0x21,0x53,0x00,0x11,0x30,0x48,0x03,0x21}, // d6
    {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x52,0x21,0x63,0x00,0x11,0x20,0x48,0x03,0x31}, // d7
    {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x52,0x21,0x63,0x00,0x11,0x00,0x48,0x03,0x31}, // d5
    {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x53,0x21,0x53,0x00,0x11,0x20,0x48,0x03,0x21}, // d6
    {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x53,0x21,0x53,0x00,0x11,0x20,0x48,0x03,0x21}, // d6
    {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x53,0x21,0x53,0x00,0x11,0x30,0x48,0x03,0x21}, // d7
    {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x53,0x21,0x53,0x00,0x11,0x20,0x48,0x03,0x21}, // d6
    {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x53,0x21,0x53,0x00,0x11,0x00,0x48,0x03,0x21}  // d4
    }; 
    
    unsigned char checksum(unsigned char *data, size_t length)
    {
        unsigned char result = 0;
        for (size_t idx = 0; idx < length; ++idx) 
        {
            result += (0x0F & data[idx]) + (data[idx] >> 4);
        }
    
        return result - 99;
    }
    
    int main(void)
    {
        for (size_t idx = 0; idx < NUM_ROWS; ++idx)
        {
            printf("%02x\n", checksum(&arr[idx][0], NUM_COLS));
        }
    }
    

    Although I'm not sure about the constant 99 above: maybe the real algorithm uses something data lengh-related. But since all rows in your sample imput have the same length, I couldn't produce a better guess.