将CRC函数从c++转换为c#

Convert CRC function from C++ to C#

本文关键字:转换 c++ CRC 函数      更新时间:2023-10-16

我正在尝试从c++转换此函数

BYTE serial::CalcCRC(BYTE start, const BYTE *buffer, DWORD lenght) 
{
    BYTE CRC = start; //...
    for(DWORD count = 0 ; count < lenght ; count++) CRC += buffer[count];
    return (0-CRC);
}

c#。这是我的c#代码:

 public byte CalcCRC(byte start, byte[] buffer, int length)
 {
     byte crc = start;
     for (int i = 0; i < length; i++) crc += buffer[i];
     return (0 - crc);
 }

但是我在最后一行得到这个错误:

错误CS0266:不能隐式地将类型"int"转换为"byte"。一个存在显式转换(您是否缺少强制类型转换?)

如何将上面的函数转换为c# ?另外,我认为c++函数可能会在大多数情况下溢出,我会在c#方面得到相同的行为吗?

好的,现在我认为cast可以解决错误-但是我会得到相同的行为与我的c#函数与c++函数,主要是由于行为可能发生在溢出等

问题是,你的原始字节被转换成一个整数的时刻,你做"0 - crc"。所以你需要做的是把最后一行

return (byte)(0-crc);

这应该能解决问题。

它将自身"转换"为整数的原因是该数值在默认情况下是整数。做Integer - Byte = Integer

编辑:关于溢出不会发生,但是为了避免可能的问题,您可以确保该值不超过255

所以你需要做的是有一个额外的检查

if( crc + buffer[i] < Byte.MaxValue )
    crc += buffer[i];

我是这样翻译的

public byte CalcCRC(byte start, byte[] buffer)
{
    unchecked
    {
        byte crc = start;
        for (int i = 0; i < buffer.Length; i++)
            crc += buffer[i];
        return (byte)(0 - crc);
    }
}

unchecked将确保溢出不会导致异常。虽然这是默认值,但它可以作为编译器选项进行更改。

这里的主要区别在于,这将不允许您输入与数组实际长度不匹配的长度。在c++中会有未定义的行为,而在c#中会抛出异常,因为c#有数组边界检查。

和overflow在c#和c++中是相同的,因为最左边的二进制数字会根据数据类型的大小被截断。