如何在C#中验证巨型十六进制数据包的CRC-16

时间:2019-06-17 13:02:03

标签: c# crc

我正在接收带有crc-16的十六进制数据包,所以我要做的就是验证此数据包是否损坏,我正在尝试计算CRC的接收方。我已经写了一些我将提供的代码,但是结果是毫无意义的值。那我在做什么错了?

我从无线设备获取此十六进制数据包,我具有生成附加到该数据包的CRC的代码。我要做的是从此数据包中获取所需的信息并将其存储在数据库中,但是现在我的问题是在CRC验证中。

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生成代码

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;
    }
}

1 个答案:

答案 0 :(得分:1)

首先将您的十六进制字符串转换为这样的字节数组:

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;
}

一旦它是字节数组,就可以通过CRC代码运行它。