最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C/C++實(shí)現(xiàn)crc碼計(jì)算和校驗(yàn)

 更新時(shí)間:2023年03月10日 11:36:04   作者:spirits_of_snail  
循環(huán)冗余校驗(yàn)(Cyclic Redundancy Check, CRC)是一種根據(jù)網(wǎng)絡(luò)數(shù)據(jù)包或計(jì)算機(jī)文件等數(shù)據(jù)產(chǎn)生簡(jiǎn)短固定位數(shù)校驗(yàn)碼的一種信道編碼技術(shù)。本文主要介紹了C++實(shí)現(xiàn)crc碼計(jì)算和校驗(yàn)的方法,需要的可以參考一下

算法介紹

循環(huán)冗余校驗(yàn)(Cyclic Redundancy Check, CRC)是一種根據(jù)網(wǎng)絡(luò)數(shù)據(jù)包或計(jì)算機(jī)文件等數(shù)據(jù)產(chǎn)生簡(jiǎn)短固定位數(shù)校驗(yàn)碼的一種信道編碼技術(shù),主要用來(lái)檢測(cè)或校驗(yàn)數(shù)據(jù)傳輸或者保存后可能出現(xiàn)的錯(cuò)誤。它是利用除法及余數(shù)的原理來(lái)作錯(cuò)誤偵測(cè)的。

CRC校驗(yàn)計(jì)算速度快,檢錯(cuò)能力強(qiáng),易于用編碼器等硬件電路實(shí)現(xiàn)。從檢錯(cuò)的正確率與速度、成本等方面,都比奇偶校驗(yàn)等校驗(yàn)方式具有優(yōu)勢(shì)。因而,CRC 成為計(jì)算機(jī)信息通信領(lǐng)域最為普遍的校驗(yàn)方式。常見(jiàn)應(yīng)用有以太網(wǎng)/USB通信,壓縮解壓,視頻編碼,圖像存儲(chǔ),磁盤(pán)讀寫(xiě)等

參數(shù)模型

CRC參數(shù)模型

不知道你是否遇到過(guò)這種情況,同樣的CRC多項(xiàng)式,調(diào)用不同的CRC計(jì)算函數(shù),得到的結(jié)果卻不一樣,而且和手算的結(jié)果也不一樣,這就涉及到CRC的參數(shù)模型了。計(jì)算一個(gè)正確的CRC值,需要知道CRC的參數(shù)模型。

一個(gè)完整的CRC參數(shù)模型應(yīng)該包含以下信息:WIDTH,POLY,INIT,REFIN,REFOUT,XOROUT。

NAME:參數(shù)模型名稱。

WIDTH:寬度,即生成的CRC數(shù)據(jù)位寬,如CRC-8,生成的CRC為8位

POLY:十六進(jìn)制多項(xiàng)式,省略最高位1,如 x8 + x2 + x + 1,二進(jìn)制為1 0000 0111,省略最高位1,轉(zhuǎn)換為十六進(jìn)制為0x07。

INIT:CRC初始值,和WIDTH位寬一致。

REFIN:true或false,在進(jìn)行計(jì)算之前,原始數(shù)據(jù)是否翻轉(zhuǎn),如原始數(shù)據(jù):0x34 = 0011 0100,如果REFIN為true,進(jìn)行翻轉(zhuǎn)之后為0010 1100 = 0x2c

REFOUT:true或false,運(yùn)算完成之后,得到的CRC值是否進(jìn)行翻轉(zhuǎn),如計(jì)算得到的CRC值:0x97 = 1001 0111,如果REFOUT為true,進(jìn)行翻轉(zhuǎn)之后為11101001 = 0xE9。

XOROUT:計(jì)算結(jié)果與此參數(shù)進(jìn)行異或運(yùn)算后得到最終的CRC值,和WIDTH位寬一致。

接收端的校驗(yàn)有兩種方式:

  • 一種是和CRC計(jì)算一樣,在本地把接收到的數(shù)據(jù)和CRC分離,然后在本地對(duì)數(shù)據(jù)進(jìn)行CRC運(yùn)算,得到的CRC值和接收到的CRC進(jìn)行比較,如果一致,說(shuō)明數(shù)據(jù)接收正確,如果不一致,說(shuō)明數(shù)據(jù)有錯(cuò)誤。
  • 另一種方法是把整個(gè)數(shù)據(jù)幀進(jìn)行CRC運(yùn)算,因?yàn)槭菙?shù)據(jù)幀相當(dāng)于把原始數(shù)據(jù)左移8位,然后加上余數(shù),如果直接對(duì)整個(gè)數(shù)據(jù)幀進(jìn)行CRC運(yùn)算(除以多項(xiàng)式),那么余數(shù)應(yīng)該為0,如果不為0說(shuō)明數(shù)據(jù)出錯(cuò)

代碼計(jì)算

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//求數(shù)的二進(jìn)制最高位的冪指數(shù),即MSB
static int getMinPolynomialBits(uint64_t n) {
	int r = 0;
	while (n >>= 1) r++;
	return r;
}

//append>0表示計(jì)算crc校驗(yàn)碼,賦值到crcRemainder
//append=0,表示校驗(yàn)輸入bit流是否正確;0表示正確,-1表示錯(cuò)誤
//此處的多項(xiàng)式默認(rèn)為0x96(高位補(bǔ)1后的結(jié)果),默認(rèn)crc位數(shù)為7,可根據(jù)代碼自行修改
static int crcCheck(const char* msg, int append, char* crcRemainder)
{
	if (msg == NULL || crcRemainder == NULL || strlen(msg) == 0) {
		printf("input parameter is unvalid!\n");
		return -1;
	}
	 //hex: 0x96 = b'10010110' = DEC:150 
	uint64_t poly = 0x96; 
	int polyLen = getMinPolynomialBits(poly + 1); //=7

	int msgLen = strlen(msg);
	//printf("%d\n", msgLen);

	//計(jì)算crc校驗(yàn)碼
	if (append) {
		unsigned char* pBufCrc = (unsigned char*)calloc(msgLen + polyLen, sizeof(unsigned char)); 
		memset(pBufCrc, 0, msgLen + polyLen);

		for (int j = 0; j < msgLen; j++) {
			pBufCrc[j] = msg[j] - '0';
		}

		uint8_t* p = NULL;
		for (int i = 0; i < msgLen; i++) {
			if (pBufCrc[i]) {
				p = pBufCrc + i + polyLen;
				uint64_t t = poly;
				do {
					*(p--) ^= t & 1;
				} while (t >>= 1);
			}
		}
		p = NULL;

		size_t k;
		for (k = 0; k < polyLen; k++) {
			crcRemainder[k] = pBufCrc[k + msgLen] + 48;
		}
		if (pBufCrc) {
			free(pBufCrc);
			pBufCrc = NULL;
		}
	}
	else {
		// 校驗(yàn)接受端的比特流
		unsigned char* pBuffer = (unsigned char*)calloc(msgLen, sizeof(unsigned char)); 
		memset(pBuffer, 0, msgLen);

		int inforLen = msgLen - polyLen;//提取出信息流部分,然后計(jì)算當(dāng)前信息對(duì)應(yīng)crc校驗(yàn)碼

		for (int j = 0; j < inforLen; j++) {
			pBuffer[j] = msg[j] - '0';
		}

		uint8_t* p = NULL;
		for (int i = 0; i < inforLen; i++) {
			if (pBuffer[i]) {
				p = pBuffer + i + polyLen;
				uint64_t t = poly;
				do {
					*(p--) ^= t & 1;
				} while (t >>= 1);
			}
		}
		p = NULL;

		//計(jì)算得到的crc碼和輸入的crc碼進(jìn)行對(duì)比驗(yàn)證,若每一位都相同,則校驗(yàn)成功
		for (size_t k = inforLen; k < msgLen; k++) {
			if (msg[k] != pBuffer[k] + 48) {
				if (pBuffer) {
					free(pBuffer);
					pBuffer = NULL;
				}
				return -1;
			}
		}
		if (pBuffer) {
			free(pBuffer);
			pBuffer = NULL;
		}
	}
	return 0;
}

到此這篇關(guān)于C/C++實(shí)現(xiàn)crc碼計(jì)算和校驗(yàn)的文章就介紹到這了,更多相關(guān)C++ crc碼內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • c++中的指針最全總結(jié)

    c++中的指針最全總結(jié)

    指針是整個(gè)C++的精髓所在,只有精通了指針才可以說(shuō)是掌握了C++,可以說(shuō)學(xué)習(xí)C++的過(guò)程是個(gè)熟練掌握和使用指針的過(guò)程,下面這篇文章主要給大家介紹了關(guān)于c++中指針的相關(guān)資料,需要的朋友可以參考下
    2024-04-04
  • C++利用遞歸實(shí)現(xiàn)走迷宮

    C++利用遞歸實(shí)現(xiàn)走迷宮

    這篇文章主要為大家詳細(xì)介紹了C++利用遞歸實(shí)現(xiàn)走迷宮,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • 關(guān)于C++的.cpp文件運(yùn)行全過(guò)程

    關(guān)于C++的.cpp文件運(yùn)行全過(guò)程

    這篇文章主要介紹了C++的.cpp文件運(yùn)行全過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • C語(yǔ)言開(kāi)源庫(kù)iniparser解析ini文件的方法

    C語(yǔ)言開(kāi)源庫(kù)iniparser解析ini文件的方法

    INI(Initialization?File)文件是一種簡(jiǎn)單直觀的數(shù)據(jù)存儲(chǔ)格式,常用于配置應(yīng)用程序的初始化設(shè)置,使用?iniparser?庫(kù)的應(yīng)用程序可以很方便地讀取和解析INI文件中的配置信息,大大簡(jiǎn)化了對(duì)配置文件的處理工作,降低了程序的開(kāi)發(fā)復(fù)雜度,感興趣的的朋友跟隨小編一起看看吧
    2024-04-04
  • 用C語(yǔ)言winform編寫(xiě)滲透測(cè)試工具實(shí)現(xiàn)SQL注入功能

    用C語(yǔ)言winform編寫(xiě)滲透測(cè)試工具實(shí)現(xiàn)SQL注入功能

    本篇文章主要介紹使用C#winform編寫(xiě)滲透測(cè)試工具,實(shí)現(xiàn)SQL注入的功能。使用python編寫(xiě)SQL注入腳本,基于get顯錯(cuò)注入的方式進(jìn)行數(shù)據(jù)庫(kù)的識(shí)別、獲取表名、獲取字段名,最終獲取用戶名和密碼;使用C#winform編寫(xiě)windows客戶端軟件調(diào)用.py腳本,實(shí)現(xiàn)用戶名和密碼的獲取
    2021-08-08
  • Visual Studio Community 2022(VS2022)安裝圖文方法

    Visual Studio Community 2022(VS2022)安裝圖文方法

    這篇文章主要介紹了Visual Studio Community 2022(VS2022)安裝方法,本文分步驟通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-09-09
  • 深入理解C++11:探索lambda函數(shù)的奧秘

    深入理解C++11:探索lambda函數(shù)的奧秘

    聚焦于C++11,讓我們一起探索lambda函數(shù)的奧秘,本指南將帶您深入了解這個(gè)強(qiáng)大的編程工具,讓您在編程世界中如虎添翼,無(wú)論您是初學(xué)者還是有經(jīng)驗(yàn)的開(kāi)發(fā)者,本指南都將為您帶來(lái)全新的視角和實(shí)用的技巧,需要的朋友可以參考下
    2024-01-01
  • C語(yǔ)言中g(shù)etchar()與putchar()函數(shù)詳解

    C語(yǔ)言中g(shù)etchar()與putchar()函數(shù)詳解

    本文主要介紹了C語(yǔ)言中g(shù)etchar()與putchar()函數(shù)詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • C++實(shí)現(xiàn)LeetCode(57.插入?yún)^(qū)間)

    C++實(shí)現(xiàn)LeetCode(57.插入?yún)^(qū)間)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(57.插入?yún)^(qū)間),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • 淺談C/C++ 語(yǔ)言中的表達(dá)式求值

    淺談C/C++ 語(yǔ)言中的表達(dá)式求值

    下面小編就為大家?guī)?lái)一篇淺談C/C++ 語(yǔ)言中的表達(dá)式求值。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-07-07

最新評(píng)論

鲜城| 凤阳县| 天柱县| 郸城县| 铅山县| 远安县| 桑植县| 鄢陵县| 钟祥市| 年辖:市辖区| 密山市| 南开区| 巴里| 汤原县| 保德县| 库车县| 绍兴市| 高尔夫| 大英县| 横峰县| 日土县| 万全县| 连州市| 潮安县| 门源| 泸定县| 清流县| 永春县| 新龙县| 双城市| 丹凤县| 正阳县| 永清县| 汉中市| 武宣县| 凌云县| 新巴尔虎右旗| 宜兰市| 重庆市| 仁寿县| 满城县|