You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中自定义CRC1校验算法实现错误排查及正确示例咨询

CRC-16 Implementation Issues and Fixes

Let's break down the problems in your code and walk through the correct implementation for your specified CRC parameters:

Identified Problems

1. Input Byte Reversal Missing

Your CRC parameters specify Refin: true, which means every input byte's bits must be reversed before processing. Your current code directly XORs the original byte with the CRC register, skipping this critical step. For example, your first byte 0x01 (binary 00000001) should be reversed to 0x80 (binary 10000000) before being used.

2. Incorrect Output Handling

  • BitConverter.GetBytes returns bytes in system-endian order (usually little-endian on x86 systems), which means a CRC value of 0x8108 would be converted to [0x08, 0x81] instead of the expected big-endian [0x81, 0x08].
  • Your parameters specify Refout: true, so the final CRC register value also needs to have its bits reversed before converting to bytes.

Fixed Implementation

First, add helper functions to reverse bits in a byte and reverse the bits of a 16-bit value:

private static byte ReverseByte(byte b)
{
    // Efficient bit reversal for a single byte
    return (byte)(((b * 0x0802LU & 0x22110LU) | (b * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16);
}

private static ushort ReverseUInt16Bits(ushort value)
{
    ushort reversed = 0;
    for (int i = 0; i < 16; i++)
    {
        reversed = (ushort)((reversed << 1) | (value & 1));
        value >>= 1;
    }
    return reversed;
}

Then update your CRC function to handle input reversal, final CRC reversal, and correct byte ordering:

/// Poly: 0x1021 (reversed to 0x8408)
/// Init: 0x0000
/// Refin: true
/// Refout: true
/// Xorout: 0x0000
public static byte[] Crc(byte[] buffer, int start = 0, int len = 0)
{
    if (buffer == null || buffer.Length == 0)
        return null;
    if (start < 0)
        return null;
    if (len == 0)
        len = buffer.Length - start;
    int length = start + len;
    if (length > buffer.Length)
        return null;

    ushort crc = 0; // Initial value
    for (int i = start; i < length; i++)
    {
        // Reverse input byte as required by Refin: true
        byte reversedByte = ReverseByte(buffer[i]);
        crc ^= reversedByte;

        for (int j = 0; j < 8; j++)
        {
            if ((crc & 1) != 0)
                crc = (ushort)((crc >> 1) ^ 0x8408); // 0x8408 is reversed 0x1021
            else
                crc = (ushort)(crc >> 1);
        }
    }

    // Reverse final CRC bits as required by Refout: true
    crc = ReverseUInt16Bits(crc);

    // Convert to big-endian byte array to match expected 0x8108 output
    byte[] ret = new byte[2];
    ret[0] = (byte)(crc >> 8);
    ret[1] = (byte)(crc & 0xFF);
    return ret;
}

With these changes, your test case (512-byte buffer starting with 0x01, rest 0x00) should return the expected 0x8108.

Where to Find Reliable CRC Implementations

  • Open Source Repositories: Look for well-maintained CRC libraries on GitHub; many include parameterized implementations that let you specify polynomial, initial value, reversal flags, and final XOR value.
  • CRC Calculators: Use online CRC calculators (with parameter customization) to validate your implementation. You can input your test data and parameters to cross-check results.
  • Standard References: The CRC Wikipedia page provides detailed explanations of CRC parameters and links to authoritative implementation guides.

内容的提问来源于stack exchange,提问作者Gemini2001

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 22:12:30