【问题标题】:Porting CRC16 Code in C to C# .NET将 C 中的 CRC16 代码移植到 C# .NET
【发布时间】:2014-07-10 22:49:40
【问题描述】:

所以我有这个需要移植到 C# 的 C 代码:

C 代码:

uint16 crc16_calc(volatile uint8* bytes, uint32 length)
{
   uint32 i; 
   uint32 j;
   uint16 crc = 0xFFFF; 
   uint16 word;

   for (i=0; i < length/2 ; i++)
   {
      word = ((uint16*)bytes)[i];

      // upper byte
      j = (uint8)((word ^ crc) >> 8);
      crc = (crc << 8) ^ crc16_table[j];

      // lower byte
      j = (uint8)((word ^ (crc >> 8)) & 0x00FF);
      crc = (crc << 8) ^ crc16_table[j];
   }
   return crc;
}

移植的 C# 代码:

public ushort CalculateChecksum(byte[] bytes)
{
    uint j = 0;
    ushort crc = 0xFFFF;
    ushort word;

    for (uint i = 0; i < bytes.Length / 2; i++)
    {
        word = bytes[i];

        // Upper byte
        j = (byte)((word ^ crc) >> 8);
        crc = (ushort)((crc << 8) ^ crc16_table[j]);

        // Lower byte
        j = (byte)((word ^ (crc >> 8)) & 0x00FF);
        crc = (ushort)((crc << 8) ^ crc16_table[j]);
    }

    return crc;
}

此 C 算法使用查找表 crc16_table[j] 计算所提供字节的 CRC16

但是移植的 C# 代码与 C 代码产生的结果不同,我做错了什么吗?

【问题讨论】:

    标签: c# c port porting crc


    【解决方案1】:
    word = ((uint16*)bytes)[i];
    

    从bytes 读取两个字节到uint16,而

    word = bytes[i];
    

    只读取一个字节。

    假设您在一个小端机器上运行,您的 C# 代码可能会更改为

    word  = bytes[i++];
    word += bytes[i] << 8;
    

    或者,根据 MerickOWA 的建议,可能更好

    word = BitConverter.ToInt16(bytes, i++);
    

    请注意,您可以通过更改循环来避免 i 看起来奇怪的额外增量:

    for (uint i = 0; i < bytes.Length; i+=2)
    {
        word = BitConverter.ToInt16(bytes, i);
    

    【讨论】:

    • 或使用 BitConverter.ToInt16
    猜你喜欢
    • 2011-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 2013-10-13
    • 2014-04-24
    • 2011-01-12
    相关资源
    最近更新 更多