Exemplo de linguagem C_algoritmo de verificação CRC

1. Introdução ao CRC

CRC (Cyclic Redundancy Check, Cyclic Redundancy Check) é uma tecnologia de detecção de erros comum usada para verificar se um erro ocorre durante a transmissão ou armazenamento de dados. Ele gera um valor de verificação e o anexa aos dados realizando uma série de cálculos e comparações nos dados. O receptor pode usar o mesmo algoritmo para verificar os dados recebidos e, em seguida, compará-los com o valor de verificação recebido para determinar se há um erro nos dados.

As verificações CRC são normalmente usadas para o seguinte:

(1) Confiabilidade da transmissão de dados: Quando os dados são transmitidos através de mídia ou redes, pode ocorrer ruído, interferência ou outros erros de transmissão. Ao adicionar um valor de verificação CRC aos dados, o receptor pode detectar se ocorreu um erro durante a transmissão e tomar as medidas correspondentes, como solicitar o reenvio dos dados.

(2) Detecção de integridade da mídia de armazenamento: Ao ler ou gravar dados na mídia de armazenamento, podem ocorrer erros como inversões de bits e falhas de mídia. Ao usar verificações CRC quando os dados são armazenados, esses erros podem ser detectados ao ler os dados e fornecer garantia de integridade dos dados.

(3) Protocolo de comunicação de rede: Muitos protocolos de comunicação de rede (como Ethernet, WiFi, USB, etc.) usam verificação CRC como parte do quadro de dados para garantir que os dados transmitidos sejam precisos. Depois de receber o quadro de dados, o receptor usa a verificação CRC para verificar a integridade dos dados.

No projeto, a verificação CRC é amplamente utilizada em vários sistemas de comunicação, sistemas de armazenamento e sistemas de transmissão de dados. Ao usar a verificação CRC, a confiabilidade dos dados pode ser melhorada e os erros no processo de transmissão ou armazenamento podem ser reduzidos. Ele pode detectar erros no nível de bit de dados e fornecer algum nível de garantia de integridade de dados. A verificação CRC desempenha um papel importante na garantia da confiabilidade e integridade dos dados, especialmente em cenários de aplicativos que possuem altos requisitos de integridade de dados.

2. Exemplo de código

O seguinte código de linguagem C demonstra como obter o valor de verificação CRC de um dado:

#include <stdio.h>
#include <stdint.h>

// CRC校验函数
uint16_t crc16(uint8_t *data, int length)
{
    
    
    uint16_t crc = 0xFFFF;
    
    for (int i = 0; i < length; i++)
    {
    
    
        crc ^= data[i];
        
        for (int j = 0; j < 8; j++)
        {
    
    
            if (crc & 1)
            {
    
    
                crc >>= 1;
                crc ^= 0xA001;
            }
            else
            {
    
    
                crc >>= 1;
            }
        }
    }
    
    return crc;
}

// 封装的CRC校验函数调用
uint16_t calculateCRC(uint8_t *data, int length)
{
    
    
    return crc16(data, length);
}

int main()
{
    
    
    uint8_t message[] = {
    
    0x01, 0x02, 0x03, 0x04, 0x05};
    int length = sizeof(message) / sizeof(message[0]);
    
    uint16_t crc = calculateCRC(message, length);
    printf("CRC: 0x%04X\n", crc);
    
    return 0;
}

No código acima, crc16a função implementa a lógica de cálculo da verificação CRC. O algoritmo CRC-16 comumente usado (polinômio 0xA001) é usado. calculateCRCA função é crc16um encapsulamento de , que é usado para chamar a função de verificação CRC e retornar o resultado da verificação.

Na mainfunção, calculateCRCcalcule o valor de verificação CRC dos dados fornecidos chamando a função e imprima o resultado.

A função de verificação CRC e a função de encapsulamento no código são calculadas com base nos tipos de dados de byte de 8 bits sem sinal e inteiro de 16 bits sem sinal.

3. Caso: verificação de dados

Cenário: Na comunicação de chip único, o chip único precisa enviar um dado para o computador host. Por exemplo, armazenado em char buff[1024]; este array. Duas funções precisam ser encapsuladas. A extremidade do chip único chama a função para executar a verificação CRC neste dado, encapsula o valor da verificação e, em seguida, o computador host verifica o CRC após receber os dados para verificar se os dados foram transmitidos corretamente .

3.1 Remetente (valor de verificação de encapsulamento)

#include <stdio.h>
#include <stdint.h>

// CRC校验函数
uint16_t crc16(uint8_t *data, int length)
{
    
    
    uint16_t crc = 0xFFFF;
    
    for (int i = 0; i < length; i++)
    {
    
    
        crc ^= data[i];
        
        for (int j = 0; j < 8; j++)
        {
    
    
            if (crc & 1)
            {
    
    
                crc >>= 1;
                crc ^= 0xA001;
            }
            else
            {
    
    
                crc >>= 1;
            }
        }
    }
    
    return crc;
}

// 封装CRC校验值到数据中
void appendCRC(uint8_t *data, int length)
{
    
    
    uint16_t crc = crc16(data, length);
    data[length] = crc & 0xFF; // 将低8位放入数据末尾
    data[length + 1] = crc >> 8; // 将高8位放入数据末尾的下一个位置
}

int main()
{
    
    
    uint8_t buff[1024] = {
    
    0x01, 0x02, 0x03, 0x04, 0x05}; // 原始数据
    int length = 5; // 数据长度
    
    // 在原始数据后追加CRC校验值
    appendCRC(buff, length);
    
    // 输出发送的数据(包括CRC校验值)
    printf("发送的数据:");
    for (int i = 0; i < length + 2; i++)
    {
    
    
        printf("%02X ", buff[i]);
    }
    printf("\n");
    
    return 0;
}

No código do remetente, use appendCRCa função para anexar o valor do cheque CRC ao final dos dados originais.

3.2 Receptor (dados de verificação)

#include <stdio.h>
#include <stdint.h>

// CRC校验函数
uint16_t crc16(uint8_t *data, int length)
{
    
    
    uint16_t crc = 0xFFFF;
    
    for (int i = 0; i < length; i++)
    {
    
    
        crc ^= data[i];
        
        for (int j = 0; j < 8; j++)
        {
    
    
            if (crc & 1)
            {
    
    
                crc >>= 1;
                crc ^= 0xA001;
            }
            else
            {
    
    
                crc >>= 1;
            }
        }
    }
    
    return crc;
}

// 验证CRC校验值是否正确
int verifyCRC(uint8_t *data, int length)
{
    
    
    uint16_t crc = crc16(data, length - 2); // 去除数据末尾的CRC校验值
    
    // 获取接收到的CRC校验值
    uint16_t receivedCRC = (data[length - 1] << 8) | data[length - 2];
    
    // 比较计算得到的CRC校验值与接收到的CRC校验值
    if (crc == receivedCRC)
    {
    
    
        return 1; // 校验通过
    }
    else
    {
    
    
        return 0; // 校验失败
    }
}

int main()
{
    
    
    uint8_t receivedData[] = {
    
    0x01, 0x02, 0x03, 0x04, 0x05, 0xC2, 0x45}; // 收到的数据(包括CRC校验值)
    int length = sizeof(receivedData) / sizeof(receivedData[0]);
    
    // 验证CRC校验值是否正确
    int crcResult = verifyCRC(receivedData, length);
    
    if (crcResult)
    {
    
    
        printf("CRC校验通过\n");
        // TODO: 进一步处理正确的数据
    }
    else
    {
    
    
        printf("CRC校验失败\n");
        // TODO: 处理校验失败的情况
    }
    
    return 0;
}

No código do receptor, use verifyCRCa função para verificar se o valor da verificação CRC dos dados recebidos está correto. Se a verificação for aprovada, outras operações de processamento de dados podem ser executadas; se a verificação falhar, o tratamento de exceções pode ser executado.

A função de verificação CRC no exemplo é calculada com base nos tipos de dados de byte de 8 bits sem sinal e inteiro de 16 bits sem sinal. Ele pode ser modificado adequadamente de acordo com as necessidades reais para se adaptar a diferentes tipos de dados e algoritmos CRC.

おすすめ

転載: blog.csdn.net/xiaolong1126626497/article/details/132145128