0

I am trying to write one program for serial port communication, where i need to send data packet with CRC, I am writing this code in C# language.

Below is sample packet which receiver is expecting with CRC.

10 02 B1 F0 3F 32 08 00 00 10 03 B4 5C

Second Data Packet : 10 02 B1 F0 3F 32 07 00 00 10 03 4D EE

10 - DLE Code

02 - STX

B1 F0 3F 32 08 00 00 are Data

10 - DLE

03 -ETX

B4 - CRC Lower Bye

5C - CRC -Upper Bye

CCIT : (Fx) = x16 + x12 + x5 + 1

Operational Initial Value: FFFFH

I tried some online CRC calculators but so far no luck, can anybody guide how to calculate CRC for above data(B1 F0 3F 32 08 00 00)? may be can suggest online calculator which can give me above output(B4 5C).

Thanks for your advise!

Suresh
  • 1,131
  • 1
  • 15
  • 28
  • This is not obvious, i suggest reading the manual to determine what is being crc'd is it the data only, is it the whole packet, nothing of this seems to make sense. – TheGeneral Jun 20 '19 at 03:33
  • Thanks for your reply, only data part needs to be include in CRC which is B1 F0 3F 32 08 00 00 – Suresh Jun 20 '19 at 04:26
  • https://crccalc.com/ there is something missing here, this doesnt seem like one of the many types of crc 16s – TheGeneral Jun 20 '19 at 04:29
  • It would help if you can get a second sample packet which doesn't differ much from the first packet, a one byte difference would help. Then you can xor the first and second sample to get data that is mostly zeroes. – rcgldr Jun 20 '19 at 05:19
  • https://en.wikipedia.org/wiki/Computation_of_cyclic_redundancy_checks – Ry- Jun 20 '19 at 05:36

2 Answers2

1

I found something that works, but it seems a bit strange.

First I xor'ed the two samples

10 02 B1 F0 3F 32 08 00 00 10 03 B4 5C
10 02 B1 F0 3F 32 07 00 00 10 03 4D EE
--------------------------------------
00 00 00 00 00 00 0F 00 00 00 00 F9 B2

This eliminates the initial CRC and final xor values, and led to using a bit reflected 0x11021 CRC. It appears that the CRC is using 8 bytes of data, including the trailing 0x10.

Using the CRC calculator linked to below, pick any CRC16, then click on custom and set parameters to: input reflected checked, output reflected checked, poly = 0x1021. There's not enough information to determine the initial value and final xor value without a different sized message. Using 8 bytes of data, some example options are: initial value = 0x5B08, final xor value = 0x0000, or initial value = 0xffff, final xor value = 0xdde5, or initial value = 0x0000, final xor value = 0xa169.

When using reflected parameters, the calculator bit reverses the init value (0x5B08 is 0x17DA bit reversed). For code, the 3 combos are {0x17da,0x0000}, (0xffff,0xdde5}, {0x0000,0xa169}. Poly = 0x8408 and is right shifting.

Using xx's to indicate ingored data, I got

xx xx B1 F0 3F 32 08 00 00 10 xx B4 5C
xx xx B1 F0 3F 32 07 00 00 10 xx 4D EE

Since the first two bytes are {10 02}, fixed values, they could be included, by changing the initial value. However, I wasn't able to include the ETX 03 value.

http://www.sunshine2k.de/coding/javascript/crc/crc_js.html

rcgldr
  • 27,407
  • 3
  • 36
  • 61
  • Thanks for your detail answer, link is helpful will try different options based on sequential data. – Suresh Jun 20 '19 at 13:57
1

Second hit I've found on the web but I copied it's contents here for reference:

using System;

public enum InitialCrcValue { Zeros, NonZero1 = 0xffff, NonZero2 = 0x1D0F }

public class Crc16Ccitt {
    const ushort poly = 4129;
    ushort[] table = new ushort[256];
    ushort initialValue = 0;

    public ushort ComputeChecksum(byte[] bytes) {
        ushort crc = this.initialValue;
        for(int i = 0; i < bytes.Length; ++i) {
            crc = (ushort)((crc << 8) ^ table[((crc >> 8) ^ (0xff & bytes[i]))]);
        }
        return crc;
    }

    public byte[] ComputeChecksumBytes(byte[] bytes) {
        ushort crc = ComputeChecksum(bytes);
        return BitConverter.GetBytes(crc);
    }

    public Crc16Ccitt(InitialCrcValue initialValue) {
        this.initialValue = (ushort)initialValue;
        ushort temp, a;
        for(int i = 0; i < table.Length; ++i) {
            temp = 0;
            a = (ushort)(i << 8);
            for(int j = 0; j < 8; ++j) {
                if(((temp ^ a) & 0x8000) != 0) {
                    temp = (ushort)((temp << 1) ^ poly);
                } else {
                    temp <<= 1;
                }
                a <<= 1;
            }
            table[i] = temp;
        }
    }
}

The original link: http://sanity-free.org/133/crc_16_ccitt_in_csharp.html

Peter
  • 14,221
  • 15
  • 70
  • 110