Search code examples
c#cbitwise-operatorscrccode-translation

Migrating CRC calculations between C and C#


I'm trying to implement crc calculation into my C# program. I've got code snippet from device C program but I'm unable to implement it into my program.

Here is code I've got:

uint16_t oblicz_crc(uint8_t* buffer, uint8_t length)
{
    uint16_t crc = 0xffff;
    uint8_t i, j;
    for(i=0;i<length;i++)
    {
    crc ^= *(buffer+i);
    for(j=0;j<8;j++)
        {
        3
        if(crc & 0x0001)
            {
            crc >>= 1;
            crc ^= 0xA001;
            }
        else
            {
            crc >>= 1;
            }
        }
    }
return(crc);
}

And there's a code I already have in my program. I assume that some of the binary operators, an "if ((crc & 0x0001) == 1)" fragment, or some of data types are wrong. Can you help me with this?

        public void Send_Frame(byte[] buffer)
        {
            byte[] checksum = Crc(buffer);  //Array.Reverse(arg) ??
            Array.Resize(ref buffer, buffer.Length + 2);
            Array.Copy(checksum, 0, buffer, buffer.Length - 2, 2);
#if DEBUG
            richTextBoxPreview.AppendText( BitConverter.ToString(buffer) + "\n");
#endif
            //Port.Write(buffer);
        }
        private byte[] Crc(byte[] buffer)
        {
            UInt16 crc = 0xFFFF;
            int i, j;
            for (i = 0; i < buffer.Length; i++)
            {
                crc ^= (ushort)(BitConverter.ToUInt16(buffer, 0) + (byte)i);
                for (j = 0; j < 8; j++)
                {
                    if ((crc & 0x0001) == 1)
                    {
                        crc >>= 1;
                        crc ^= 0xA001;
                    }
                    else
                    {
                        crc >>= 1;
                    }
                }
            }
            return BitConverter.GetBytes(crc);
        }

PS: This question is about my specific code snippet. When I get answer will it be best to delete it? Or should I leave it ?


Solution

  • The problem is at this line:

    crc ^= (ushort)(BitConverter.ToUInt16(buffer, 0) + (byte)i);
    

    In the original code its:

    crc ^= *(buffer+i);
    

    The original code is adding i to the buffer pointer, and dereferencing that location. If you change the code to:

    crc ^=  (ushort)(buffer[i]);
    

    then you're actually doing the same operation.