簡體   English   中英

將CRC計算從C#轉換為C

[英]Convert CRC calculation from C# to C

我目前正在使用串行監視器,以確保某些數據的完整性,我正在嘗試實現CRC8校驗和,以下是在我發送任何消息之前對任何消息進行的計算。

public byte Checksum(params byte[] val)
{
    if (val == null)
        throw new ArgumentNullException("val");
    byte c = 0;
    foreach (byte b in val)
    {
        c = table[c ^ b];
    }
    return c;
}

我使用0xD8生成表:

public byte[] GenerateTable(CRC8_POLY polynomial)
{
    byte[] csTable = new byte[256];
    for (int i = 0; i < 256; ++i)
    {
        int curr = i;
        for (int j = 0; j < 8; ++j)
        {
            if ((curr & 0x80) != 0)
            {
            curr = (curr << 1) ^ (int)polynomial;
            }
            else
            {
                curr <<= 1;
            }
        }
        csTable[i] = (byte)curr;
    }
    return csTable;
}

這是我用於測試設置的代碼:

private void btnSend_Click(object sender, EventArgs e)
{
    ProtoFrame rxFrame = new ProtoFrame();
    if (cboParam.Text == "test")
    {
        rxFrame.Start = 0x73;
        rxFrame.Size = 9;
        rxFrame.Command = 01;
        rxFrame.Unused = 0;
        rxFrame.ParamId = 0x0100;
        rxFrame.Param = 8000;
    }

    byte[] rxBuffer = getBytes(rxFrame); //call to byte array formatter
    rxBuffer[rxBuffer.Length-1] = Checksum(rxBuffer); //append crc at end of array
    ComPort.Write(rxBuffer, 0, rxBuffer.Length);
}
static byte[] getBytes(object str) //input struct
{
    int size = Marshal.SizeOf(str) + 1;
    byte[] arr = new byte[size];
    IntPtr ptr = Marshal.AllocHGlobal(size);

    Marshal.StructureToPtr(str, ptr, true);
    Marshal.Copy(ptr, arr, 0, size);
    Marshal.FreeHGlobal(ptr);

    return arr;
}

據我所知,此代碼按預期工作,並且我使用表生成器在我的微控制器中實現了硬編碼表,從而加快了處理速度。
我不太了解的是如何以與此處類似的方式實現函數來計算CRC。 朝着正確方向的任何幫助或指導表示贊賞。 到目前為止,我已經提出了這個功能:

uint8_t crc8(uint8_t *crc)
{
    uint8_t crcVal;
    int m;
    for (m = 0; m < PacketSize ;m++ )startbyte
    {
        *crc = crc8_table[(*crc) ^ m];
        *crc &= 0xFF;        
    }
}

表在哪里:

uint8_t crc8_table[256] = {0,24,48,40,96,120,80,72,192,216,240,232,160,184,144,136,88,64,104,112,56,32,8,16,
                    152,128,168,176,248,224,200,208,176,168,128,152,208,200,224,248,112,104,64,88,16,8,
                    32,56,232,240,216,192,136,144,184,160,40,48,24,0,72,80,120,96,184,160,136,144,216,
                    192,232,240,120,96,72,80,24,0,40,48,224,248,208,200,128,152,176,168,32,56,16,8,64,
                    88,112,104,8,16,56,32,104,112,88,64,200,208,248,224,168,176,152,128,80,72,96,120,48,
                    40,0,24,144,136,160,184,240,232,192,216,168,176,152,128,200,208,248,224,104,112,88,
                    64,8,16,56,32,240,232,192,216,144,136,160,184,48,40,0,24,80,72,96,120,24,0,40,48,120,
                    96,72,80,216,192,232,240,184,160,136,144,64,88,112,104,32,56,16,8,128,152,176,168,224,
                    248,208,200,16,8,32,56,112,104,64,88,208,200,224,248,176,168,128,152,72,80,120,96,40,
                    48,24,0,136,144,184,160,232,240,216,192,160,184,144,136,192,216,240,232,96,120,80,72,
                    0,24,48,40,248,224,200,208,152,128,168,176,56,32,8,16,88,64,104,112
                    };

從rxFrame.Size中找到PacketSize

因此,您只需要將C#函數移植到C

public byte Checksum(params byte[] val)
{
    if (val == null)
        throw new ArgumentNullException("val");
    byte c = 0;
    foreach (byte b in val)
    {
        c = table[c ^ b];
    }
    return c;
}

C中沒有例外。使用返回值表示錯誤,並添加一個將用作返回值的參數。 由您決定是將消息長度作為參數傳遞還是將其保留在全局范圍內:

int checksum(uint8_t const *msg, size_t msglen, uint8_t *result)

foreach循環轉換為for循環,其中i是index, msg[i]foreachb

int checksum(uint8_t const *msg, size_t msglen, uint8_t *result)
{
    if (msg == NULL || msglen == 0)
        return 0;

    uint8_t crc = 0;
    for (int i = 0; i < msglen; i++)
    {
        crc = table[crc ^ msg[i]];
    }

存儲結果並返回成功代碼:

int checksum(uint8_t const *msg, size_t msglen, uint8_t *result)
{
    if (msg == NULL || msglen == 0)
        return 0;

    uint8_t crc = 0;
    for (int i = 0; i < msglen; i++)
    {
        crc = table[crc ^ msg[i]];
    }

    *result = crc;
    return 1;
}

用法:

uint8_t crc;
if (!checksum(message, PacketSize, &crc))
    report_error();

查看C#代碼應該是:

uint8_t crc8(uint8_t const *crc, size_t size)
{
    unit8_t c = 0;
    size_t  m;
    for (m = 0; m < size; m++ )
    {
        c = crc8_table[c ^ *crc];
        crc++;
    }

    return c;
}

不使用指針,轉換為數組

        public static byte crc8(byte[] crc)
         {
             byte crcVal;
             int m;
             for (m = 0; m < PacketSize; m++)
             {
                 crc[m] = crc8_table[crc[m] ^ m];
                 crc[m] &= 0xFF;
             }
             return crcVal;
         }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM