Search code examples
c#ccrc16

Converting CRC16 calculation from C to C#


I have to translate a CRC16 calculation from C to C# but get the message that I cannot implicitly convert type 'int' to 'bool' on the (crc & 0x8000) and on return (crc & 0xFFFF)

The code so far:

public unsafe short Crc16(string str)
{
    short crc = 0;

    for(int i = 0; i < str.Length; i++)
    {
        crc = (crc << 1) ^ str[i] ^ ((crc & 0x8000) ? 0x1021 : 0);
    }
    return (crc & 0xFFFF);
}

EDIT: Changed char parameter to string

Original C code

short Crc16( char *str )
{
    short crc=0;
    unsigned int i;
    for (i=0; i<strlen(str); i++)
        crc = (crc << 1) ^ *(str+i) ^ ((crc & 0x8000)? 0x1021:0 );
    return (crc & 0xffff);
}

Solution

  • In C, 0 and FALSE are synonymous, and any number that is not 0 is true. (reference)

    To make the conversion you would do it something like this:

    public short CalcCrc16(string str)
    {
        short crc = 0;
        int i;
    
        unchecked
        {
            foreach(char c in str)
            {
                short exponent = (crc & 0x8000) != 0 ? 0x1021 : 0;
                crc = (crc << 1) ^ ((short)c) ^ exponent);
            }
    
            return (short)(crc & 0xFFFF);
        }
    }
    

    So now that we have the C code to work with, I changed the code sample I have here to match. Below is the explanation of the changes:

    • char* is the C equivalent of a string
    • The for loop is iterating over the characters *(str + i) can be rewritten as str[i], and is equivalent to C#'s str.GetChar(i)
    • The ternary condition is to determine whether the exponent is 0x1021 or 0.
    • I broke up the lines so you could see the algorithm a bit clearer.
    • I changed for(int i = 0; i < str.Length; i++) to a foreach on the characters because it was easier to understand.