Search code examples
c#crc

How to verify CRC-16 of a giant hex packet in C#


I'm receiving a hexadecimal packet with crc-16, so what i have to do is verify if this packet is corrupted or not, I'm doing it trying to calculate the receiver side of CRC. I have wrote some code that i will provide, but the result of it are meaningless values. So what am I doing wrong ?

I'm getting this hexadecimal packet from a wireless device, I have the code that generates the CRC that is attached to the packet. What I have to do is get the information that i need from this packet and store in a Data Base, but for now my problem is in CRC verify.

public class CrcReceiver
{
    private static String polynom = "A001";


    //ToBinary method
    public static string hexToBinary(String hexString)
    {
        String binary = "";
        for (int i = 0; i < hexString.Length; i++)
        {
            binary = binary + Convert.ToString(Convert.ToInt32(hexString.Substring(i, 1), 16), 2).PadLeft(4, '0');
        }
        binary = binary.TrimStart('0');
        return binary;
    }

    public static String CrcCheck(String pacote)//passing the packet as parameter
    {
        String binaryPolynom;//binary polynom
        String binaryPacket;//binary packet
        String substring;
        int inicio = 0;//determines the start of the substring
        String xorResult;
        int diferenca = 0;//gets the difference between xorResult and binaryPolynom           
        int xorResultLength;

        binaryPacket = hexToBinary(pacote);

        binaryPolynom = hexToBinary(polynom);

        int polyLength = binaryPolynom.Length;

        substring = binaryPacket.Substring(inicio, polyLength);

        inicio += polyLength;          

        while (inicio < binaryPacket.Length)
        {
            xorResult = xor(substring, binaryPolynom);
            xorResult = xorResult.TrimStart('0');
            xorResultLength = xorResult.Length;

            if(xorResultLength < polyLength)
            {
                if ((polyLength - xorResultLength) + inicio <= binaryPacket.Length)
                {
                    diferenca = polyLength - xorResultLength;                 
                    substring = binaryPacket.Substring(inicio, diferenca);
                    inicio += diferenca;
                    xorResult += substring;
                }
                else
                {
                    substring = binaryPacket.Substring(inicio, (binaryPacket.Length - inicio));
                    inicio += substring.Length;
                    xorResult += substring;
                }
            }

            substring = xorResult;   

        }

        return xor(substring, binaryPolynom);
    }


    //Xor method
    private static String xor(String Element1, String Element2)
    {
        String novaString = "";

        for(int i = 0; i < Element1.Length; i++)
        {
            if(Element1[i] != Element2[i])
            {
                novaString += '1';
            }
            else
            {
                novaString += '0';
            }
        }

        return novaString;
    }

}

CRC generation code

public sealed class CRC
{
    private readonly int _polynom;

    public static readonly CRC Default = new CRC(0xA001);

    public CRC(int polynom)
    {
        _polynom = polynom;
    }

    public int CalcCrc16(byte[] buffer)
    {
        return CalcCrc16(buffer, 0, buffer.Length, _polynom, 0);
    }

    public static int CalcCrc16(byte[] buffer, int offset, int bufLen, int polynom, int preset)
    {
        preset &= 0xFFFF;
        polynom &= 0xFFFF;

        var crc = preset;
        for (var i = 0; i < bufLen; i++)
        {
            var data = buffer[(i + offset) % buffer.Length] & 0xFF;
            crc ^= data;
            for (var j = 0; j < 8; j++)
            {
                if ((crc & 0x0001) != 0)
                {
                    crc = (crc >> 1) ^ polynom;
                }
                else
                {
                    crc = crc >> 1;
                }
            }
        }
        return crc & 0xFFFF;
    }
}

Solution

  • Start by converting your hex string to a byte array like this:

    public static byte[] StringToByteArray(String hex)
    {
      int NumberChars = hex.Length;
      byte[] bytes = new byte[NumberChars / 2];
      for (int i = 0; i < NumberChars; i += 2)
        bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
      return bytes;
    }
    

    Once it is a byte array then you can run it through your CRC code.