将CRC16代码用C语言移植到C#.NET

Eri*_*man 0 c c# port porting crc

所以我有这个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;
}
Run Code Online (Sandbox Code Playgroud)

移植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;
}
Run Code Online (Sandbox Code Playgroud)

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

但是,Ported C#代码不能产生与C代码相同的结果,我做错了吗?

sim*_*onc 5

word = ((uint16*)bytes)[i];
Run Code Online (Sandbox Code Playgroud)

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

word = bytes[i];
Run Code Online (Sandbox Code Playgroud)

只读一个字节.

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

word  = bytes[i++];
word += bytes[i] << 8;
Run Code Online (Sandbox Code Playgroud)

或者,可能更好,正如MerickOWA所建议的那样

word = BitConverter.ToInt16(bytes, i++);
Run Code Online (Sandbox Code Playgroud)

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

for (uint i = 0; i < bytes.Length; i+=2)
{
    word = BitConverter.ToInt16(bytes, i);
Run Code Online (Sandbox Code Playgroud)