日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

得到CRC16校验码的常见几个标准的算法及C语言实现

發布時間:2025/6/15 编程问答 10 豆豆
生活随笔 收集整理的這篇文章主要介紹了 得到CRC16校验码的常见几个标准的算法及C语言实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

CRC16常見的標準有以下幾種,被用在各個規范中,其算法原理基本一致,就是在數據的輸入和輸出有所差異,下邊把這些標準的差異列出,并給出C語言的算法實現。

CRC16_CCITT:多項式x16+x12+x5+1(0x1021),初始值0x0000,低位在前,高位在后,結果與0x0000異或

CRC16_CCITT_FALSE:多項式x16+x12+x5+1(0x1021),初始值0xFFFF,低位在后,高位在前,結果與0x0000異或

CRC16_XMODEM:多項式x16+x12+x5+1(0x1021),初始值0x0000,低位在后,高位在前,結果與0x0000異或

CRC16_X25:多項式x16+x12+x5+1(0x1021),初始值0x0000,低位在前,高位在后,結果與0xFFFF異或

?

CRC16_MODBUS:多項式x16+x15+x2+1(0x8005),初始值0xFFFF,低位在前,高位在后,結果與0x0000異或

CRC16_IBM:多項式x16+x15+x2+1(0x8005),初始值0x0000,低位在前,高位在后,結果與0x0000異或

CRC16_MAXIM:多項式x16+x15+x2+1(0x8005),初始值0x0000,低位在前,高位在后,結果與0xFFFF異或

CRC16_USB:多項式x16+x15+x2+1(0x8005),初始值0xFFFF,低位在前,高位在后,結果與0xFFFF異或

?

模式

多項式

初始值

數據位序

結果處理

CRC16_CCITT

x16+x12+x5+1(0x1021)

0x0000

低位在前,高位在后

與0x0000異或

CRC16_CCITT_FALSE

x16+x12+x5+1(0x1021)

0xFFFF

低位在后,高位在前

與0x0000異或

CRC16_XMODEM

x16+x12+x5+1(0x1021)

0x0000

低位在后,高位在前

與0x0000異或

CRC16_X25

x16+x12+x5+1(0x1021)

0x0000

低位在后,高位在前

與0xFFFF異或

CRC16_ MODBUS

x16+x15+x2+1(0x8005)

0xFFFF

低位在前,高位在后

與0x0000異或

CRC16_ IBM

x16+x15+x2+1(0x8005)

0x0000

低位在前,高位在后

與0x0000異或

CRC16_ MAXIM

x16+x15+x2+1(0x8005)

0x0000

低位在前,高位在后

與0xFFFF異或

CRC16_ USB

x16+x15+x2+1(0x8005)

0xFFFF

低位在前,高位在后

與0xFFFF異或

多項式產生:
如x16+x12+x5+1
x16表示第16位為1,x5表示第5位為1
(1 << 16) | (1 << 12) | (1 << 5) | (1) = 0x11021
但是CRC16只取低16位,寫成16進制數就是 0x1021

CRC16的算法原理:

1.根據CRC16的標準選擇初值CRCIn的值。

2.將數據的第一個字節與CRCIn高8位異或。

3.判斷最高位,若該位為 0 左移一位,若為 1 左移一位再與多項式Hex碼異或。

4.重復3直至8位全部移位計算結束。

5.重復將所有輸入數據操作完成以上步驟,所得16位數即16位CRC校驗碼。

根據算法原理與標準要求就能簡單的寫出具體程序:

unsigned short CRC16_CCITT(unsigned char *puchMsg, unsigned int usDataLen) {unsigned short wCRCin = 0x0000;unsigned short wCPoly = 0x1021;unsigned char wChar = 0;while (usDataLen--) {wChar = *(puchMsg++);InvertUint8(&wChar,&wChar);wCRCin ^= (wChar << 8);for(int i = 0;i < 8;i++){if(wCRCin & 0x8000)wCRCin = (wCRCin << 1) ^ wCPoly;elsewCRCin = wCRCin << 1;}}InvertUint16(&wCRCin,&wCRCin);return (wCRCin) ; } unsigned short CRC16_CCITT_FALSE(unsigned char *puchMsg, unsigned int usDataLen) {unsigned short wCRCin = 0xFFFF;unsigned short wCPoly = 0x1021;unsigned char wChar = 0;while (usDataLen--) {wChar = *(puchMsg++);wCRCin ^= (wChar << 8);for(int i = 0;i < 8;i++){if(wCRCin & 0x8000)wCRCin = (wCRCin << 1) ^ wCPoly;elsewCRCin = wCRCin << 1;}}return (wCRCin) ; } unsigned short CRC16_XMODEM(unsigned char *puchMsg, unsigned int usDataLen) {unsigned short wCRCin = 0x0000;unsigned short wCPoly = 0x1021;unsigned char wChar = 0;while (usDataLen--) {wChar = *(puchMsg++);wCRCin ^= (wChar << 8);for(int i = 0;i < 8;i++){if(wCRCin & 0x8000)wCRCin = (wCRCin << 1) ^ wCPoly;elsewCRCin = wCRCin << 1;}}return (wCRCin) ; }unsigned short CRC16_X25(unsigned char *puchMsg, unsigned int usDataLen) {unsigned short wCRCin = 0xFFFF;unsigned short wCPoly = 0x1021;unsigned char wChar = 0;while (usDataLen--) {wChar = *(puchMsg++);InvertUint8(&wChar,&wChar);wCRCin ^= (wChar << 8);for(int i = 0;i < 8;i++){if(wCRCin & 0x8000)wCRCin = (wCRCin << 1) ^ wCPoly;elsewCRCin = wCRCin << 1;}}InvertUint16(&wCRCin,&wCRCin);return (wCRCin^0xFFFF) ; }unsigned short CRC16_MODBUS(unsigned char *puchMsg, unsigned int usDataLen) {unsigned short wCRCin = 0xFFFF;unsigned short wCPoly = 0x8005;unsigned char wChar = 0;while (usDataLen--) {wChar = *(puchMsg++);InvertUint8(&wChar,&wChar);wCRCin ^= (wChar << 8);for(int i = 0;i < 8;i++){if(wCRCin & 0x8000)wCRCin = (wCRCin << 1) ^ wCPoly;elsewCRCin = wCRCin << 1;}}InvertUint16(&wCRCin,&wCRCin);return (wCRCin) ; } unsigned short CRC16_IBM(unsigned char *puchMsg, unsigned int usDataLen) {unsigned short wCRCin = 0x0000;unsigned short wCPoly = 0x8005;unsigned char wChar = 0;while (usDataLen--) {wChar = *(puchMsg++);InvertUint8(&wChar,&wChar);wCRCin ^= (wChar << 8);for(int i = 0;i < 8;i++){if(wCRCin & 0x8000)wCRCin = (wCRCin << 1) ^ wCPoly;elsewCRCin = wCRCin << 1;}}InvertUint16(&wCRCin,&wCRCin);return (wCRCin) ; } unsigned short CRC16_MAXIM(unsigned char *puchMsg, unsigned int usDataLen) {unsigned short wCRCin = 0x0000;unsigned short wCPoly = 0x8005;unsigned char wChar = 0;while (usDataLen--) {wChar = *(puchMsg++);InvertUint8(&wChar,&wChar);wCRCin ^= (wChar << 8);for(int i = 0;i < 8;i++){if(wCRCin & 0x8000)wCRCin = (wCRCin << 1) ^ wCPoly;elsewCRCin = wCRCin << 1;}}InvertUint16(&wCRCin,&wCRCin);return (wCRCin^0xFFFF) ; } unsigned short CRC16_USB(unsigned char *puchMsg, unsigned int usDataLen) {unsigned short wCRCin = 0xFFFF;unsigned short wCPoly = 0x8005;unsigned char wChar = 0;while (usDataLen--) {wChar = *(puchMsg++);InvertUint8(&wChar,&wChar);wCRCin ^= (wChar << 8);for(int i = 0;i < 8;i++){if(wCRCin & 0x8000)wCRCin = (wCRCin << 1) ^ wCPoly;elsewCRCin = wCRCin << 1;}}InvertUint16(&wCRCin,&wCRCin);return (wCRCin^0xFFFF) ; } void InvertUint8(unsigned char *dBuf,unsigned char *srcBuf) {int i;unsigned char tmp[4];tmp[0] = 0;for(i=0;i< 8;i++){if(srcBuf[0]& (1 << i))tmp[0]|=1<<(7-i);}dBuf[0] = tmp[0];} void InvertUint16(unsigned short *dBuf,unsigned short *srcBuf) {int i;unsigned short tmp[4];tmp[0] = 0;for(i=0;i< 16;i++){if(srcBuf[0]& (1 << i))tmp[0]|=1<<(15 - i);}dBuf[0] = tmp[0]; } void InvertUint32(unsigned int *dBuf,unsigned int *srcBuf) {int i;unsigned int tmp[4];tmp[0] = 0;for(i=0;i< 32;i++){if(srcBuf[0]& (1 << i))tmp[0]|=1<<(15 - i);}dBuf[0] = tmp[0]; }

具體驗證使用這個工具,內含CRC算法的計算,和后邊的博客中提到的其他算法的工具合集

加密解密算法工具集

在這個基礎上也加入CRC32 的校驗算法

//CRC32算法: unsigned int CRC32(unsigned char *puchMsg, unsigned int usDataLen) {int i;unsigned int wCRCin = 0xFFFFFFFF;unsigned int wCPoly = 0x04C11DB7;unsigned int wChar = 0;while (usDataLen--) {wChar = *(puchMsg++);InvertUint8((unsigned char *)&wChar,(unsigned char *)&wChar);wCRCin ^= (wChar << 24);for(i = 0;i < 8;i++){if(wCRCin & 0x80000000)wCRCin = (wCRCin << 1) ^ wCPoly;elsewCRCin = wCRCin << 1;}}InvertUint32(&wCRCin,&wCRCin);return (wCRCin ^ 0xFFFFFFFF) ; }

對于CRC32可能還有其他的多項式和初始值和結果值是否需要異或以及輸入數據是否需要位序倒轉等要求在源碼中修改

總結

以上是生活随笔為你收集整理的得到CRC16校验码的常见几个标准的算法及C语言实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。