【问题标题】:What's the importance of the Offset variable in this algorithm?Offset 变量在这个算法中的重要性是什么?
【发布时间】:2019-06-18 17:12:09
【问题描述】:

这个算法中这个名为 Offset 的变量是什么意思? 它在第二个 calcCrc16 参数中声明。 对我来说,它是无用的,因为它是零并且它被用于总和。

此算法生成一个 crc-16。我试图理解这个算法,因为必须创建一个验证 crc-16 的算法,并且我想使用这个代码作为基础。

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 + 2); 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;
    }
}

【问题讨论】:

  • 原始数据数组中的起始位置。如果您不希望标头参与 CRC 计算,则可以将其设置为非零值。

标签: c# variables crc


【解决方案1】:

我创建了一个简单的示例,使用一个小的 4 字节消息(在一个 6 字节缓冲区中):

using System;
namespace crc16
{
    class Program
    {
        private static ushort Crc16(byte[] bfr, int bfrlen)
        {
            ushort crc = 0;
            for (int i = 0; i < bfrlen; i++)
            {
                crc ^= bfr[i];
                for (int j = 0; j < 8; j++)
                    // assumes twos complement math
                    crc = (ushort)((crc >> 1)^((0 - (crc&1)) & 0xa001));
            }
            return crc;
        }

        static void Main(string[] args)
        {
            ushort crc;
            byte[] data = new byte[6] {0x11, 0x22, 0x33, 0x44, 0x00, 0x00};
            crc = Crc16(data, 4);           // generate crc
            data[4] = (byte)(crc & 0xff);   // append crc (lsb first)
            data[5] = (byte)(crc >> 8);
            crc = Crc16(data, 6);           // verify crc;
            Console.WriteLine("{0:X4}", crc);
            return;
        }
    }
}

【讨论】:

  • 你得到 0 作为结果?
  • 第一次调用返回 4 字节消息的 CRC,第二次调用返回 0。
  • @Levi - 如果这对您有用,您可能需要考虑删除其他问题。
【解决方案2】:

它是 public 方法签名的一部分,适用于您想要计算 CRC 的任何时候,但不适用于整个缓冲区。

当然,大多数时候您可能只使用该方法的简单版本,在这种情况下,参数始终为零,但通常散列和 CRC 实现是使用这样的 API 构建的,允许您计算 CRC如果你愿意,可以分块。

【讨论】:

  • 谢谢,我可以再问一个问题吗?我正在尝试使用相同的算法来制作无线通信的接收端,所以我必须验证 crc-16,你有什么建议我如何调整这个代码来实现这个功能?
  • @Levi - 假设 CRC16 附加到消息中,然后使用 buflen+2 并验证返回的 CRC 为 0x0000。
  • @rcgldr 我试过用你说的,我用了 buflen + 2,但我仍然无法得到 0x0000 作为答案。我已经为您编辑了示例算法以供您查看 cange。
猜你喜欢
  • 1970-01-01
  • 2014-10-28
  • 1970-01-01
  • 1970-01-01
  • 2015-01-29
  • 1970-01-01
  • 2010-12-03
  • 1970-01-01
  • 2014-09-12
相关资源
最近更新 更多