crc檢驗演算法
Ⅰ 關於CRC效驗
為保證傳輸過程的正確性,需要對通信過程進行差錯控制。差錯控制最常用的方法是自動請求重發方式(ARQ)、向前糾錯方式(FEC)和混合糾錯(HEC)。在傳輸過程誤碼率比較低時,用FEC方式比較理想。在傳輸過程誤碼率較高時,採用FEC容易出現「亂糾」現象。HEC方式則是ARQ和FEC的結合。在許多數字通信中,廣泛採用ARQ方式,此時的差錯控制只需要檢錯功能。實現檢錯功能的差錯控制方法很多,傳統的有:奇偶校驗、校驗和檢測、重復碼校驗、恆比碼校驗、行列冗餘碼校驗等,這些方法都是增加數據的冗餘量,將校驗碼和數據一起發送到接受端。接受端對接受到的數據進行相同校驗,再將得到的校驗碼和接受到的校驗碼比較,如果二者一致則認為傳輸正確。但這些方法都有各自的缺點,誤判的概率比較高。
循環冗餘校驗CRC(Cyclic Rendancy Check)是由分組線性碼的分支而來,其主要應用是二元碼組。編碼簡單且誤判概率很低,在通信系統中得到了廣泛的應用。下面重點介紹了CRC校驗的原理及其演算法實現。
CRC校驗可以100%地檢測出所有奇數個隨機錯誤和長度小於等於k(k為g(x)的階數)的突發錯誤。所以CRC的生成多項式的階數越高,那麼誤判的概率就越小。
CRC代碼的一些基本概念和運算:
CRC多項式:
例:
代碼:1010111 對應的多項式為:X6+X4+X2+X+1
多項式X5+X3+X2+X1+1對應的代碼為101111
CRC生成多項式:
首位和最後一位必須是1。CRC生成多項式是給定的,在傳輸過程中不變,即發送和接收端生成碼相同。
一些常用的校驗碼為:
CRC8=X8+X5+X4+1
CRC-CCITT=X16+X12+X5+1
CRC16=X16+X15+X5+1
CRC12=X12+X11+X3+X2+1
CRC32=X32+X26+X23+X22+X16+X12+X11+X10+X8+X7+X5+X4+X2+X1+1
CRC的運算本質是異或運算(模2除法)
例:原信息碼為1011001
生成碼為11001
校驗碼計算過程
① 將信息碼左移4位(生成碼長-1);得到10110010000
② 異或運算
10110010000
11001
01111010000(前面的數進行異或運算,後面的直接抄下來)
11001
0011110000(和生成碼異或運算的必須從1開始)
11001
00111000
11001
001010
這樣得到的結果為1010,即為所需要的校驗碼,添加到信息碼後,得到發送的代碼為:
10110011010
我把上面的手算過程用c#寫了一段程序,如下:
using System;
namespace mainClass
{
public class mainProgress
{
public static void Main()
{
byte[] msg={1,0,1,1,0,0,1};//信息碼
byte[] gmsg=new byte[msg.Length+4];
crc c = new crc();
gmsg=c.code(msg);
Console.Write("編碼後字元串為:");
for (int i = 0; i < gmsg.Length; i++)
{
Console.Write("{0}", gmsg[i].ToString());
}
Console.Write("\n");
byte[] gmsg1={ 1, 0, 1, 1, 0, 1, 1 };//接收到的代碼
bool r = c.det(gmsg1);
if (r)
{
Console.WriteLine("傳輸正確");
}
else
{ Console.WriteLine("傳輸錯誤"); }
}
}
public class crc//CRC編碼類
{
private byte[] g = { 1,1,0,0,1};//生成碼
public byte[] code(byte[] msg)//編碼
{
byte[] gmsg=new byte[g.Length+msg.Length-1];
msg.CopyTo(gmsg, 0);//
for (int i = 0; i < msg.Length; i++)//完成異或運算,即模2除法
{
if (gmsg[i] == 1)
{
for (int j = 0; j < g.Length; j++)
{
if (gmsg[i + j] == g[j])
gmsg[i + j] = 0;
else
gmsg[i + j] = 1;
}
}
}
msg.CopyTo(gmsg, 0);
return gmsg;
}
private bool f=true;
//接收端檢測
public bool det(byte[] gmsg)
{
for (int i = 0; i < gmsg.Length - g.Length+1; i++)
{
if(gmsg[i]==0)
continue;
for (int j = 0; j < g.Length; j++)
{
if (gmsg[i + j] == g[j])
gmsg[i + j] = 0;
else
gmsg[i + j] = 1;
}
}
for (int i = 0; i < gmsg.Length; i++)
{
if (gmsg[i] == 1)
f = false;
}
return f;
}
}
}
Ⅱ modbus中如何計算CRC效驗(人工計算)
在CRC計算時只用8個數據位,起始位及停止位,如有奇偶校驗位也包括奇偶校驗位,都不參與CRC計算。
CRC計算方法是:
1、 載入一值為0XFFFF的16位寄存器,此寄存器為CRC寄存器。
2、 把第一個8位二進制數據(即通訊信息幀的第一個位元組)與16位的CRC寄存器的相異或,異或的結果仍存放於該CRC寄存器中。
3、 把CRC寄存器的內容右移一位,用0填補最高位,並檢測移出位是0還是1。
4、 如果移出位為零,則重復第三步(再次右移一位);如果移出位為1,CRC寄存器與0XA001進行異或。
(2)crc檢驗演算法擴展閱讀:
計算步驟為:
(1).預置 16 位寄存器為十六進制 FFFF(即全為 1) ,稱此寄存器為 CRC 寄存器;
(2).把第一個 8 位數據與 16 位 CRC 寄存器的低位相異或,把結果放於 CRC 寄
存器;
(3).檢測相異或後的CRC寄存器的最低位,若最低位為1:CRC寄存器先右移1位,再與多項式A001H進行異或;若為0,則CRC寄存器右移1位,無需與多項式進行異或。
(4).重復步驟 3 ,直到右移 8 次,這樣整個 8 位數據全部進行了處理;
(5).重復步驟 2 到步驟4,進行下一個 8 位數據的處理;
(6).最後得到的 CRC 寄存器即為 CRC 碼。
Ⅲ CRC校驗的演算法
在代數編碼理論中,將一個碼組表示為一個多項式,碼組中各碼元當作多項式的系數。例如 1100101 表示為1·x6+1·x5+0·x4+0·x3+1·x2+0·x+1,即 x6+x5+x2+1。
設編碼前的原始信息多項式為P(x),P(x)的最高冪次加1等於k;生成多項式為G(x),G(x)的最高冪次等於r;CRC多項式為R(x);編碼後的帶CRC的信息多項式為T(x)。
發送方編碼方法:將P(x)乘以xr(即對應的二進制碼序列左移r位),再除以G(x),所得余式即為R(x)。用公式表示為T(x)=xrP(x)+R(x)
接收方解碼方法:將T(x)除以G(x),得到一個數,如果這個余數為0,則說明傳輸中無錯誤發生,否則說明傳輸有誤。
舉例來說,設信息編碼為1100,生成多項式為1011,即P(x)=x3+x2,G(x)=x3+x+1,計算CRC的過程為
xrP(x) =x3(x3+x2) = x6+x5 G(x)= x3+x+1 即 R(x)=x。注意到G(x)最高冪次r=3,得出CRC為010。
如果用豎式除法(計算機的模二,計算過程為
1110 ------- 1011 /1100000 (1100左移3位) 1011 ---- 1110 1011 ----- 1010 1011 ----- 0010 0000 ---- 010 因此,T(x)=(x6+x5)+(x)=x6+x5+x, 即 1100000+010=1100010
如果傳輸無誤,
T(x)= (x6+x5+x)/G(x) = , G(x)= 無余式。回頭看一下上面的豎式除法,如果被除數是1100010,顯然在商第三個1時,就能除盡。
上述推算過程,有助於我們理解CRC的概念。但直接編程來實現上面的演算法,不僅繁瑣,效率也不高。實際上在工程中不會直接這樣去計算和驗證CRC。
下表中列出了一些見於標準的CRC資料:
名稱 生成多項式 簡記式* 應用舉例
CRC-4 x4+x+1 3 ITU G.704
CRC-8 x8+x5+x4+1 31 DS18B20
CRC-12 x12+x11+x3+x2+x+1 80F
CRC-16 x16+x15+x2+1 8005 IBM SDLC
CRC-ITU** x16+x12+x5+1 1021 ISO HDLC, ITU X.25, V.34/V.41/V.42, PPP-FCS,ZigBee
CRC-32 x32+x26+x23+...+x2+x+1 04C11DB7 ZIP, RAR, IEEE 802 LAN/FDDI,IEEE 1394,PPP-FCS
CRC-32c x32+x28+x27+...+x8+x6+1 1EDC6F41 SCTP
* 生成多項式的最高冪次項系數是固定的1,故在簡記式中,將最高的1統一去掉了,如04C11DB7實際上是104C11DB7。 ** 前稱CRC-CCITT。ITU的前身是CCITT。
備註:
(1)生成多項式是標准規定的
(2)CRC校驗碼是基於將位串看作是系數為0或1的多項式,一個k位的數據流可以看作是關於x的從k-1階到0階的k-1次多項式的系數序列。採用此編碼,發送方和接收方必須事先商定一個生成多項式G(x),其高位和低位必須是1。要計算m位的幀M(x)的校驗和,基本思想是將校驗和加在幀的末尾,使這個帶校驗和的幀的多項式能被G(x)除盡。當接收方收到加有校驗和的幀時,用G(x)去除它,如果有餘數,則CRC校驗錯誤,只有沒有餘數的校驗才是正確的。
Ⅳ 誰能把crc校驗一步步算出來
從(1)看,你已經考慮了演算法要求的初值問題,從(3)看,你已經考慮了數據的排列問題,使用的是低位先傳輸低位先校驗的方式,那還有兩個問題:
計算步驟,從你的講述上,你是先判斷最低位為1,做異或,再移位,這個步驟不符合要求。應該是先判斷最低位為1,先移位,再做異或;如果最低位為0,則移位,但不做異或。具體的原理一下說不清楚,我借花獻佛,推薦你搜一下一個文檔:「我學習CRC32、CRC16、CRC 原理和演算法的總結(與WINRAR 結果一致)」,其中「三 直接計演算法」可以解決你的問題,但建議你把之前的一二都看了,我前段時間做以太正橘網的CRC32校驗的時候被整的死去活來,最後發現這個文檔講得很有條理,雖然應用不同,但原理相同,感謝作者。
確定一下你最後的CRC碼是否需要取反,因為很多傳輸用的演算法,帶清沒如果要對CRC校驗碼後的0的個數敏感,是需要對其CRC碼取反的,你做完1後,如果結果還不對,可以試著取反試試。最後再確定一下演算法要求的CRC碼值的排放順序,這個也會影響你最終結果的表現形式。
差點被你繞進去了,你的計算是使用的檢查最低位蠢納,向右移的方式,那你的生成多項式是不是也已經相應的進行了翻轉?將高低位按序反著放了?建議你還是找到你要做的這個演算法的規範文本,確認一下規則。
Ⅳ 循環冗餘校驗(CRC)碼
與海明校驗碼類似,CRC碼也是數據通訊中常用的校驗方式。
CRC 演算法的基本思想是將傳輸的數據當做一個位數很長的數。將這個數除以另一個數。得到的余數作為校驗數據附加到原數據後面。
與海明校驗碼數據位和校驗位穿插不同,CRC碼中,校驗位(R位)在信息位(K位)後面
以一個慎碧高題目為例:設待校驗的數據為。D8~D1 = 10101011,若採用CRC,且生成多項式為 10011,則其 CRC 碼為:
這里首先要注意題目中的一個表述——「多項式」,該題目中寫作「10011」,在有的題目中往往寫作「x^4+x+1」
首先,在數據位後加 多項式最高冪次 個0,比如這里的多項式最高次項為x^4,那就在數據位後加四個0,變成:101010110000,作為被除數
然後,將多項式 10011 作為除數進行斷除。需要注意的是,圖中所框的部分,對應位只做xor運算,也就是做減法但不影響其他位
最後得到的余數:1010,即是校驗位。那麼寬尺整個CRC碼為:10101011 1010
以上一節例題為例,假設收到的CRC碼變成了10001011 1010,第10位(右邊為低位)發生了錯誤。
現在嘗試慧嫌用CRC碼與多項式 10011 進行短除:
得到余數為 1010(2) = 1 8+1 2 = 10(10) ,即第10位發生錯誤,只需要反轉第10位的值,便可獲得正確的值
Ⅵ CRC16校驗碼如何計算
首先G(X)=X3+X+1可以得出G(x)=1011[G(x)中的1就是二進制第0位為1,X就是第一位為1,沒有X^2,所以第二位為0,X^3則第三位為1。所以就是1011]
M(x)=0011M(x)*x3=0011000
M(x)*x3/G(x)的余數是101所以R(X)=101
CRC碼為:M(x)*x3+R(x)=0011000+010=0011010
在計算機網路通信中
運用CRC校驗時相對於其他校驗方法就有一定的優勢。CRC可以高比例的糾正信息傳輸過程中的錯誤,可以在極短的時間內完成數據校驗碼的計算,並迅速完成糾錯過程,通過數據包自動重發的方式使得計算機的通信速度大幅提高,對通信效率和安全提供了保障。由於CRC演算法檢驗的檢錯能力極強,且檢測成本較低,因此在對於編碼器和電路的檢測中使用較為廣泛。
以上內容參考:網路-CRC
Ⅶ 如何校驗CRC值
作二進制除法。
1、亮野發送數據比特序列為1101011011(10比特)。
2、生成多項式比特序列為10011(5比特,K=4),X的指數就是代表第幾位為1,而且1=X的0次方。
3、將發送數據比特序列乘以2的K(由2可知K為4),那麼產生的乘積為11010110110000。
4、將乘積用生成多項式比特序列去除,按模二演算法得到余數1110。
模二演算法就是兩數相減不產生借位,0-1=1。
步驟如如下所示:
(7)crc檢驗演算法擴展閱讀:
二進制除法的CRC校驗原理。
RC校驗原理看起來比較復雜,因為大多枯謹數書上基本上是以二進制的多項式形式來說明的。其實很簡單的問題,其根本思想就是先在要發送的幀後面附加一個數(這個就是用來校驗的校驗碼,但要注意,這里的數也是二進制序列的,下同),生成一個新幀發送給接收端。
當然,這個附加的數不是隨意的,它要使所生成的新幀能與發送端和接收端共同選定的某個特定數整除(注意,這里不是直接採用二進制除法,而是採用一種稱之為「模2除法」)。到達接收端後,再把接收到的新幀除以(同樣採用「模2除法」)這個選定的除數。因為在發送端發送數據幀之前就已通過附加一個數,做了「去余」處理(也就已經能整除了),所以結果應該是沒有餘數。
如果有餘數,則表明該幀在傳輸過程中出現了差錯。
【詳細說明】「模2除法」與「算術除法」類似,但它既不向上位借位,也不比較除數和被除數的相同位數值的大小,只要以相同位數進行相除即可。模2加法運算為:1+1=0,0+1=1,0+0=0,無進位,也無借位;模2減法運算為:1-1=0,0-1=1,1-0=1,0-0=0,也無進位,無借位。
相當於二進制中的邏輯異或運算。也就是比沒鍵基較後,兩者對應位相同則結果為「0」,不同則結果為「1」。如100101除以1110,結果得到商為11,余數為1。
參考資料來源:網路--CRC校驗
Ⅷ 求CRC校驗計算方法
你這個是CRC16
要實現校驗的話,你首先需要知道對方採用的是何種CRC公式
不同的CRC公式 得到的校驗碼是不一樣的
在知道公式的情況下
做crc表,然後按照crc演算法,計算這8個位元組的整體crc
如果傳輸沒有錯誤的話,最終的crc值是0
也可以計算前六個的crc,然後和最後兩個位元組比較,效果是相同的。
Ⅸ crc校驗碼計算方法是什麼
已知信息位為1100,生成多項式G(x) = x3+x+1,求CRC碼。
M(x) = 1100 M(x)*x3 = 1100000 G(x) = 1011
M(x)*x3 / G(x) = 1110 + 010 /1011 R(x) = 010
CRC碼為: M(x)*x 3+R(x)=1100000+010 =1100010
其原理是:CRC碼一般在k位信息位之後拼接r位校驗位生成。編碼步驟如下:
(1)將待編碼的k位信息表示成多項式 M(x)。
(2)將 M(x)左移 r 位,得到 M(x)*xr 。
(3)用r+1位的生成多項式G(x)去除M(x)*xr 得到余數R(x)。
(4)將M(x)*xr 與R(x)作模2加,得到CRC碼。
(9)crc檢驗演算法擴展閱讀:
CRC校驗碼計算詳解:採用CRC進行差錯檢驗,生成多項式為G(X)=X4+X+1,信息碼字為10110,則計算出的CRC校驗碼是:A. 0000 B. 0100 C. 0010 D.1111
符號表示假定:多項式和多項式的系數排列均用相同的符號表示,如
G(X)= X4+X+1
G(X)=10011
已知條件如下:
原碼字記做M(X),即:M(X) = 10110
生成多項式記做G(X),即:G(X) = 10011
G(X)的最高階數記做r,此處r = 4
Ⅹ CRC校驗全解
這幾天一直在看CRC校驗演算法。CRC版本眾多,網站上實現演算法一大坨,可一開始根本搞不清楚那個是哪個。連續上網路,嗶哩嗶哩,知乎看了很多解讀CRC演算法的,終於有了一些眉目,打算寫下來,方便日後參考。
CRC演算法核心其實只有一種,即二進制除法的實現橘清,版本眾多的原因主要有以下幾個原因:
CRC欄位的長度
多項式公式
初始值
輸出是否水平翻轉
輸入是否水平翻轉
結果異或值
我絕大多數的文章都只談到了CRC欄位的長度和多項式公式,沒有涉及剩餘的三項在crc演算法中的應用。
CRC欄位的長度 ,欄位越長,對於crc演算法的校驗能力越強。如果我們用出錯的概率來評宏旦估校驗能力的話。N長度的欄位,他的校驗能力為1/2**N。此處的運算符號採用Python語言中的含義。
一般而言,我們取的長度主要有8位,16位和32位。當然也有一些比較奇特的,4位,5位和6位,還有7位。
多項式公式 是我們二進制多項蔽伍擾式演算法中的除數。不同的演算法往往取的多項式是不一樣的。
初始值 ,是指CRC欄位的初始值。常常是從0和全是1中選擇。
輸入反轉。 具體的操作方法實施將輸入的數據按照位元組為單位進行水平反轉。比如01000001,翻轉結果是10000010。
輸出翻轉 。輸出翻轉的操作與輸入翻轉操作是一樣的。只是輸出翻轉是將整個CRC欄位進行水平翻轉。
結果異或值 ,是用來和 通過上述的演算法算出來的結果 進行異或的一個數據值。如果這個值是0的話,那麼就相當於沒有進行異或。
為什麼需要這么多看起來亂七八糟的種類呢。這些演算法分別針對不同的數據的檢驗。針對不同的數據的特性,比如說某些數據,一開始就會有大量的零,如果不採用輸入翻轉或者初始值的話,那麼這些0就對於校驗結果沒有任何影響。這就如我們想要的結果有出入了,我們希望校驗結果和數據是一一對應的,並且是唯一的。如果不唯一那麼,校驗結果也就失去了意義。因此這么多演算法的出現,主要原因就是為了適應不同的數據字元串的特點。
下面就是一些例子了。
驗證網站: http://www.ip33.com/crc.html