亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C語(yǔ)言實(shí)現(xiàn)CRC校驗(yàn)算法的示例詳解

 更新時(shí)間:2023年08月09日 16:26:08   作者:DS小龍哥  
CRC(Cyclic Redundancy Check,循環(huán)冗余校驗(yàn))是一種常用的錯(cuò)誤檢測(cè)技術(shù),用于驗(yàn)證數(shù)據(jù)在傳輸或存儲(chǔ)過(guò)程中是否發(fā)生了錯(cuò)誤,本文主要介紹了C語(yǔ)言如何實(shí)現(xiàn)CRC校驗(yàn)算法,需要的可以參考一下

一、CRC介紹

CRC(Cyclic Redundancy Check,循環(huán)冗余校驗(yàn))是一種常用的錯(cuò)誤檢測(cè)技術(shù),用于驗(yàn)證數(shù)據(jù)在傳輸或存儲(chǔ)過(guò)程中是否發(fā)生了錯(cuò)誤。它通過(guò)對(duì)數(shù)據(jù)進(jìn)行一系列計(jì)算和比較,生成一個(gè)校驗(yàn)值,并將其附加到數(shù)據(jù)中。接收方可以使用相同的算法對(duì)接收到的數(shù)據(jù)進(jìn)行校驗(yàn),然后與接收到的校驗(yàn)值進(jìn)行比較,從而確定數(shù)據(jù)是否存在錯(cuò)誤。

CRC校驗(yàn)通常用于以下方面:

(1)數(shù)據(jù)傳輸?shù)目煽啃裕涸跀?shù)據(jù)通過(guò)媒體或網(wǎng)絡(luò)進(jìn)行傳輸時(shí),可能會(huì)發(fā)生噪聲、干擾或其他傳輸錯(cuò)誤。通過(guò)在數(shù)據(jù)中添加CRC校驗(yàn)值,接收方可以檢測(cè)到傳輸過(guò)程中是否發(fā)生了錯(cuò)誤,并采取相應(yīng)措施,如請(qǐng)求重新發(fā)送數(shù)據(jù)。

(2)存儲(chǔ)介質(zhì)的完整性檢測(cè):在存儲(chǔ)介質(zhì)上讀取或?qū)懭霐?shù)據(jù)時(shí),可能會(huì)發(fā)生位翻轉(zhuǎn)、介質(zhì)故障等錯(cuò)誤。通過(guò)在數(shù)據(jù)存儲(chǔ)時(shí)使用CRC校驗(yàn),可以在讀取數(shù)據(jù)時(shí)檢測(cè)到這些錯(cuò)誤,并提供數(shù)據(jù)的完整性保證。

(3)網(wǎng)絡(luò)通信協(xié)議:許多網(wǎng)絡(luò)通信協(xié)議(如Ethernet、WiFi、USB等)使用CRC校驗(yàn)作為數(shù)據(jù)幀的一部分,以確保傳輸?shù)臄?shù)據(jù)準(zhǔn)確無(wú)誤。接收方在接收到數(shù)據(jù)幀后,使用CRC校驗(yàn)來(lái)驗(yàn)證數(shù)據(jù)的完整性。

在項(xiàng)目中,CRC校驗(yàn)廣泛應(yīng)用于各種通信系統(tǒng)、存儲(chǔ)系統(tǒng)和數(shù)據(jù)傳輸系統(tǒng)中。通過(guò)使用CRC校驗(yàn),可以提高數(shù)據(jù)的可靠性,并減少傳輸或存儲(chǔ)過(guò)程中的錯(cuò)誤。它可以檢測(cè)到數(shù)據(jù)位級(jí)別的錯(cuò)誤,并提供一定程度的數(shù)據(jù)完整性保證。CRC校驗(yàn)在保障數(shù)據(jù)可靠性和完整性方面具有重要作用,特別是在對(duì)數(shù)據(jù)完整性有較高要求的應(yīng)用場(chǎng)景中。

二、示例代碼

以下C語(yǔ)言代碼演示如何獲取一段數(shù)據(jù)的CRC校驗(yàn)值:

#include <stdio.h>
#include <stdint.h>
?
// CRC校驗(yàn)函數(shù)
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校驗(yàn)函數(shù)調(diào)用
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;
}

在上面代碼中,crc16 函數(shù)實(shí)現(xiàn)了CRC校驗(yàn)的計(jì)算邏輯。采用了常用的CRC-16算法(0xA001多項(xiàng)式)。calculateCRC 函數(shù)是對(duì) crc16 的封裝,用于調(diào)用CRC校驗(yàn)函數(shù)并返回校驗(yàn)結(jié)果。

main 函數(shù)中,通過(guò)調(diào)用 calculateCRC 函數(shù)來(lái)計(jì)算給定數(shù)據(jù)的CRC校驗(yàn)值,并將結(jié)果打印輸出。

代碼中的CRC校驗(yàn)函數(shù)和封裝函數(shù)是基于無(wú)符號(hào)8位字節(jié)和無(wú)符號(hào)16位整數(shù)的數(shù)據(jù)類型進(jìn)行計(jì)算的。

三、案例:數(shù)據(jù)校驗(yàn)

場(chǎng)景:在單片機(jī)通信里,單片機(jī)需要向上位機(jī)發(fā)送一段數(shù)據(jù)。比如,存放在char buff[1024];這個(gè)數(shù)組里。 需要封裝兩個(gè)函數(shù),單片機(jī)端調(diào)用函數(shù)對(duì)這段數(shù)據(jù)進(jìn)行CRC校驗(yàn),封裝校驗(yàn)值,然后上位機(jī)收到數(shù)據(jù)之后驗(yàn)證CRC,校驗(yàn)數(shù)據(jù)是否傳輸正確。

3.1 發(fā)送方(封裝校驗(yàn)值)

#include <stdio.h>
#include <stdint.h>
?
// CRC校驗(yàn)函數(shù)
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校驗(yàn)值到數(shù)據(jù)中
void appendCRC(uint8_t *data, int length)
{
 ? ?uint16_t crc = crc16(data, length);
 ? ?data[length] = crc & 0xFF; // 將低8位放入數(shù)據(jù)末尾
 ? ?data[length + 1] = crc >> 8; // 將高8位放入數(shù)據(jù)末尾的下一個(gè)位置
}
?
int main()
{
 ? ?uint8_t buff[1024] = {0x01, 0x02, 0x03, 0x04, 0x05}; // 原始數(shù)據(jù)
 ? ?int length = 5; // 數(shù)據(jù)長(zhǎng)度
 ? ?// 在原始數(shù)據(jù)后追加CRC校驗(yàn)值
 ? ?appendCRC(buff, length);
 ? ?// 輸出發(fā)送的數(shù)據(jù)(包括CRC校驗(yàn)值)
 ? ?printf("發(fā)送的數(shù)據(jù):");
 ? ?for (int i = 0; i < length + 2; i++)
 ?  {
 ? ? ? ?printf("%02X ", buff[i]);
 ?  }
 ? ?printf("\n");
 ? ?return 0;
}

在發(fā)送方的代碼中,使用 appendCRC 函數(shù)將CRC校驗(yàn)值追加到原始數(shù)據(jù)的末尾。

3.2 接收方(校驗(yàn)數(shù)據(jù))

#include <stdio.h>
#include <stdint.h>
?
// CRC校驗(yàn)函數(shù)
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;
}
?
// 驗(yàn)證CRC校驗(yàn)值是否正確
int verifyCRC(uint8_t *data, int length)
{
 ? ?uint16_t crc = crc16(data, length - 2); // 去除數(shù)據(jù)末尾的CRC校驗(yàn)值
 ? ?// 獲取接收到的CRC校驗(yàn)值
 ? ?uint16_t receivedCRC = (data[length - 1] << 8) | data[length - 2];
 ? ?// 比較計(jì)算得到的CRC校驗(yàn)值與接收到的CRC校驗(yàn)值
 ? ?if (crc == receivedCRC)
 ?  {
 ? ? ? ?return 1; // 校驗(yàn)通過(guò)
 ?  }
 ? ?else
 ?  {
 ? ? ? ?return 0; // 校驗(yàn)失敗
 ?  }
}
?
int main()
{
 ? ?uint8_t receivedData[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0xC2, 0x45}; // 收到的數(shù)據(jù)(包括CRC校驗(yàn)值)
 ? ?int length = sizeof(receivedData) / sizeof(receivedData[0]);
 ? ?// 驗(yàn)證CRC校驗(yàn)值是否正確
 ? ?int crcResult = verifyCRC(receivedData, length);
 ? ?if (crcResult)
 ?  {
 ? ? ? ?printf("CRC校驗(yàn)通過(guò)\n");
 ? ? ? ?// TODO: 進(jìn)一步處理正確的數(shù)據(jù)
 ?  }
 ? ?else
 ?  {
 ? ? ? ?printf("CRC校驗(yàn)失敗\n");
 ? ? ? ?// TODO: 處理校驗(yàn)失敗的情況
 ?  }
 ? ?return 0;
}

在接收方的代碼中,使用 verifyCRC 函數(shù)驗(yàn)證接收到的數(shù)據(jù)的CRC校驗(yàn)值是否正確。如果校驗(yàn)通過(guò),可以執(zhí)行進(jìn)一步的數(shù)據(jù)處理操作;如果校驗(yàn)失敗,可以進(jìn)行異常處理。

示例中的CRC校驗(yàn)函數(shù)是基于無(wú)符號(hào)8位字節(jié)和無(wú)符號(hào)16位整數(shù)的數(shù)據(jù)類型進(jìn)行計(jì)算的??梢愿鶕?jù)實(shí)際需求進(jìn)行適當(dāng)修改,以適應(yīng)不同的數(shù)據(jù)類型和CRC算法。

到此這篇關(guān)于C語(yǔ)言實(shí)現(xiàn)CRC校驗(yàn)算法的示例詳解的文章就介紹到這了,更多相關(guān)C語(yǔ)言CRC校驗(yàn)算法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語(yǔ)言與C++中內(nèi)存管理詳解

    C語(yǔ)言與C++中內(nèi)存管理詳解

    本章主要介紹C語(yǔ)言與C++的內(nèi)存管理,以C++的內(nèi)存分布作為引入,介紹C++不同于C語(yǔ)言的內(nèi)存管理方式(new?delete對(duì)比?malloc?free),感興趣的朋友來(lái)看看吧
    2022-04-04
  • C++中關(guān)于union的使用方法說(shuō)明

    C++中關(guān)于union的使用方法說(shuō)明

    這篇文章主要介紹了C++中關(guān)于union的使用方法說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • C語(yǔ)言實(shí)現(xiàn)單鏈表的示例詳解

    C語(yǔ)言實(shí)現(xiàn)單鏈表的示例詳解

    給需要考研的同學(xué)一個(gè)參考,單鏈表作為常見(jiàn)數(shù)據(jù)結(jié)構(gòu)的一種,這里記錄C語(yǔ)言實(shí)現(xiàn)單鏈表,文章通過(guò)代碼示例介紹的非常詳細(xì),具有一頂?shù)膮⒖純r(jià)值,需要的朋友可以參考下
    2023-09-09
  • C++實(shí)現(xiàn)矩陣原地轉(zhuǎn)置算法

    C++實(shí)現(xiàn)矩陣原地轉(zhuǎn)置算法

    這篇文章主要介紹了C++實(shí)現(xiàn)矩陣原地轉(zhuǎn)置算法,非常經(jīng)典的算法,需要的朋友可以參考下
    2014-08-08
  • c語(yǔ)言字符數(shù)組與字符串的使用詳解

    c語(yǔ)言字符數(shù)組與字符串的使用詳解

    本篇文章是對(duì)c語(yǔ)言中字符數(shù)組與字符串的使用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • stl容器set,map,vector之erase用法與返回值詳細(xì)解析

    stl容器set,map,vector之erase用法與返回值詳細(xì)解析

    在使用 list、set 或 map遍歷刪除某些元素時(shí)可以這樣使用,如下所示
    2013-09-09
  • C++多重繼承二義性原理實(shí)例解析

    C++多重繼承二義性原理實(shí)例解析

    這篇文章主要介紹了C++多重繼承二義性原理實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-06-06
  • 詳解C++ 模板編程

    詳解C++ 模板編程

    模板(template)是C++實(shí)現(xiàn)泛型(Generics)和元編程(Meta Programming)的基礎(chǔ)。本文拋磚引玉,簡(jiǎn)要介紹C++模板編程,不足之處敬請(qǐng)指正。
    2020-09-09
  • VC打印word,excel文本文件的方法

    VC打印word,excel文本文件的方法

    這篇文章主要介紹了VC打印word,excel文本文件的方法,是VC操作文本文件中非常實(shí)用的技巧,需要的朋友可以參考下
    2014-10-10
  • C語(yǔ)言中的字符型數(shù)據(jù)與ASCII碼表

    C語(yǔ)言中的字符型數(shù)據(jù)與ASCII碼表

    這篇文章主要介紹了C語(yǔ)言中的字符型數(shù)據(jù)與ASCII碼表,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-01-01

最新評(píng)論