0

I'm searching to calculate CRC-16 for concox VTS. After search a lot I've got several formula, lookup table, CRC32.net library etc and tried them. But didn't get the actual result which I've wanted.

For example, when I use crc32.net library :

byte[] data = { 11, 01, 03, 51, 51, 00, 94, 10, 95, 20, 20, 08, 25, 81, 00, 23 };
UInt32 crcOut = Crc32Algorithm.ComputeAndWriteToEnd(data);
Console.WriteLine(crcOut.ToString());

It returns : 3232021645

But actually it should return : 90DD

I've tried another example too but they also did not return proper value.

Edit :

Here is the RAW data from Device :

{78}{78}{11}{01}{03}{51}{51}{00}{94}{10}{95}{20}{20}{08}{25}{81}{00}{23}{90}{DD}{0D}{0A}

When split by following data sheet, it looks like -

{78}{78}    =   Start Bit
{11}        =   Packet Length(17) = (01 + 12 + 02 + 02) =  Decimal 17 = Hexadecimal 11      
{01}        =   Protocol No
{03}{51}{51}{00}{94}{10}{95}{20}    =   TerminalID  =   0351510094109520
{20}{08}    =   Model Identification Code
{25}{81}    =   Time Zone Language
{00}{23}    =   Information Serial No
{90}{DD}    =   Error Check (CRC : Packet Length to Information Serial No)
{0D}{0A}    =   Stop Bit

They told in error check it need CRC from Packet Length to Information Serial No. To make reply this packet I also need to make a data packet with CRC code.

I've found an online calculator from below link. The data match with CRC-16/X-25.

Now I need to calculate it by C# code.

https://crccalc.com/?crc=11,%2001,%2003,%2051,%2051,%2000,%2094,%2010,%2095,%2020,%2020,%2008,%2025,%2081,%2000,%2023&method=CRC-16/X-25&datatype=hex&outtype=0

Waiting for your reply.

Thanks

Maruf Hossain
  • 101
  • 1
  • 3
  • 17
  • Did you already see these question? https://stackoverflow.com/questions/22860356/how-to-generate-a-crc-16-from-c-sharp https://stackoverflow.com/questions/31953396/calculating-crc16-in-c-sharp – Klaus Gütter Jan 16 '23 at 07:43
  • Tried, but did not match my requirement. I'll send a byte array any it should return CRC-16/X-25 calculative data. – Maruf Hossain Jan 16 '23 at 12:12
  • Interesting. It looks like CRC32.net is actually computing the CRC-32C, using the Castagnoli polynomial. That's also what the Intel crc32 instructions aid in computing. – Mark Adler Jan 16 '23 at 20:03
  • I've found from an article that this CRC32.NET can also calculate CRC16 format data. But I can't calculate CRC-16 from this library. – Maruf Hossain Jan 18 '23 at 04:00

3 Answers3

4

The CRC-16 you assert that you need in your comment (which needs to be in your question) is the CRC-16/X-25. On your data, that CRC gives 0xcac0, not 0x90dd.

In fact, none of the documented CRC-16's listed in that catalog produce 0x90dd for your data. You need to provide a reference for the CRC that you need, and how you determined that 0x90dd is the expected result for that data.

Update for updated question:

The bytes you provided in your example data are in decimal:

byte[] data = { 11, 01, 03, 51, 51, 00, 94, 10, 95, 20, 20, 08, 25, 81, 00, 23 };

That is completely wrong, since, based on the actual data message data in your updated question that you want the CRC for, those digits must be interpreted as hexadecimal. (Just by chance, none of those numbers have hexadecimal digits in a..f.) To represent that test vector in your code correctly, it needs to be:

byte[] data = { 0x11, 0x01, 0x03, 0x51, 0x51, 0x00, 0x94, 0x10, 0x95, 0x20, 0x20, 0x08, 0x25, 0x81, 0x00, 0x23 };

This computes the CRC-16/X-25:

ushort crc16_x25(byte[] data, int len) {
    ushort crc = 0xffff;
    for (int i = 0; i < len; i++) {
        crc ^= data[i];
        for (unsigned k = 0; k < 8; k++)
            crc = (crc & 1) != 0 ? (crc >> 1) ^ 0x8408 : crc >> 1;
    }
    return ~crc;
}
Mark Adler
  • 101,978
  • 13
  • 118
  • 158
  • Please visit the following link : https://crccalc.com/?crc=11,%2001,%2003,%2051,%2051,%2000,%2094,%2010,%2095,%2020,%2020,%2008,%2025,%2081,%2000,%2023&method=CRC-16/X-25&datatype=hex&outtype=0 After submit data See on "CRC-16/X-25" section. I need to calculate this value. – Maruf Hossain Jan 18 '23 at 03:55
0

Try this code, I modified it from this example https://gist.github.com/andresv/4611897 (Thank you Andresv)

uint16_t x25crc16(unsigned char *data_p, uint16_t lenght) {
    uint16_t crc = 0xFFFF;
    uint32_t data;
    uint16_t crc16_table[] = {
            0x0000, 0x1081, 0x2102, 0x3183,
            0x4204, 0x5285, 0x6306, 0x7387,
            0x8408, 0x9489, 0xa50a, 0xb58b,
            0xc60c, 0xd68d, 0xe70e, 0xf78f
    };

    while(lenght--){
        crc = ( crc >> 4 ) ^ crc16_table[(crc & 0xf) ^ (*data_p & 0xf)];
        crc = ( crc >> 4 ) ^ crc16_table[(crc & 0xf) ^ (*data_p++ >> 4)];
    }

    data = crc;
    return (~crc);
}

Test with an array of characters

int main()
{
    uint8_t ascii_arr[9] =  {'1', '2', '3', '4', '5', '6', '7', '8', '9'};
    uint16_t checksum = 0;
    printf("\"%s\"\n", ascii_arr);

    checksum = x25crc16(ascii_arr, 9);
    printf("CRC-16 X-25: 0x%x\n", checksum );
    return 0;
}

Output is:

"123456789"
CRC-16 X-25: 0x906e

You can compare with this online CRC calculator https://crccalc.com/?crc=123456789&method=CRC-16/X-25&datatype=ascii&outtype=0

0

Probably you are wrong but i tried input in crccalc web page and in one app that i use for calculate crc 16-X25

11 01 03 51 51 00 94 10 95 29 29 08 25 81 00 23

and both gives me 0xF497

I'll share you my code in C

Hope it helps

uint16_t CRC_crc16(const uint8_t *pData, uint16_t num_bytes)
{  
  static volatile uint16_t crc; 
  static volatile uint8_t i, byte, temp;
    
    crc = 0xffff;    // Reset crc
    do 
    { 
        for (i = 0, byte = *pData++; i < 8; i++, byte >>= 1) 
        { 
            temp = (uint8_t) ((uint8_t) crc & (uint8_t) 0x01); 
            crc >>= 1; 
            if (temp ^ (byte & 0x01)) 
            crc ^= 0x8408; 
        }
    } 
    while (--num_bytes); 
  
  crc = ~((crc << 8) | (crc >> 8));
  return crc;
}

crc16 X25 Calc