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代码相同的结果,我做错了吗?
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)