?? vb下如何編寫(xiě)crc校驗(yàn)程序.htm
字號(hào):
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0056)http://vbboshi.myrice.com/vbtech/other/page_2/file44.htm -->
<HTML><HEAD><TITLE>VB下如何編寫(xiě)CRC校驗(yàn)程序</TITLE>
<META content=en-us http-equiv=Content-Language>
<META content="text/html; charset=gb2312" http-equiv=Content-Type>
<META content="MSHTML 5.00.2614.3500" name=GENERATOR>
<META content=FrontPage.Editor.Document name=ProgId>
<STYLE type=text/css>FONT {
FONT-SIZE: 9pt; LINE-HEIGHT: 13pt
}
P {
FONT-SIZE: 9pt; LINE-HEIGHT: 13pt
}
TD {
FONT-SIZE: 9pt; LINE-HEIGHT: 13pt
}
SELECT {
FONT-FAMILY: 宋體; FONT-SIZE: 9pt
}
INPUT {
FONT-FAMILY: 宋體; FONT-SIZE: 9pt
}
TEXTAREA {
FONT-FAMILY: 宋體; FONT-SIZE: 9pt
}
A {
COLOR: blue; FONT-SIZE: 9pt; TEXT-DECORATION: none
}
A:hover {
COLOR: red; TEXT-DECORATION: underline
}
A:active {
COLOR: red; TEXT-DECORATION: underline
}
</STYLE>
</HEAD>
<BODY bgColor=#feeaa5>
<DIV align=center>
<CENTER>
<TABLE border=0 width="100%">
<TBODY>
<TR>
<TD align=middle width="100%"><FONT
color=#ff0000>VB下如何編寫(xiě)CRC校驗(yàn)程序<BR></FONT>作者:欒金奎</TD></TR>
<TR>
<TD> 隨著計(jì)算機(jī)技術(shù)的不斷發(fā)展,在現(xiàn)代工業(yè)中,利用微機(jī)進(jìn)行數(shù)據(jù)通訊的工業(yè)控制應(yīng)用得也越來(lái)越廣泛。由于傳輸距離、現(xiàn)場(chǎng)狀況等諸多可能出現(xiàn)的因素影響,計(jì)算機(jī)與受控設(shè)備之間的通訊數(shù)據(jù)常會(huì)發(fā)生無(wú)法預(yù)測(cè)的錯(cuò)誤。為了防止錯(cuò)誤所帶來(lái)的影響,一般在通訊時(shí)采取數(shù)據(jù)校驗(yàn)的辦法,而循環(huán)冗余碼校驗(yàn)是最常用的校驗(yàn)方法之一。<BR><BR>一、
循環(huán)冗余碼校驗(yàn)原理<BR><BR> 循環(huán)冗余碼校驗(yàn)英文名稱(chēng)為Cyclical Redundancy
Check,簡(jiǎn)稱(chēng)CRC。它是利用除法及余數(shù)的原理來(lái)作錯(cuò)誤偵測(cè)(Error
Detecting)的。實(shí)際應(yīng)用時(shí),發(fā)送裝置計(jì)算出CRC值并隨數(shù)據(jù)一同發(fā)送給接收裝置,接收裝置對(duì)收到的數(shù)據(jù)重新計(jì)算CRC并與收到的CRC相比較,若兩個(gè)CRC值不同,則說(shuō)明數(shù)據(jù)通訊出現(xiàn)錯(cuò)誤。<BR>根據(jù)應(yīng)用環(huán)境與習(xí)慣的不同,CRC又可分為以下幾種標(biāo)準(zhǔn):<BR> ①CRC-12碼;<BR> ②CRC-16碼;<BR> ③CRC-CCITT碼;<BR> ④CRC-32碼。<BR> CRC-12碼通常用來(lái)傳送6-bit字符串。CRC-16及CRC-CCITT碼則用是來(lái)傳送8-bit字符,其中CRC-16為美國(guó)采用,而CRC-CCITT為歐洲國(guó)家所采用。CRC-32碼大都被采用在一種稱(chēng)為Point-to-Point的同步傳輸中。<BR>下面以最常用的CRC-16為例來(lái)說(shuō)明其生成過(guò)程。<BR> CRC-16碼由兩個(gè)字節(jié)構(gòu)成,在開(kāi)始時(shí)CRC寄存器的每一位都預(yù)置為1,然后把CRC寄存器與8-bit的數(shù)據(jù)進(jìn)行異或,之后對(duì)CRC寄存器從高到低進(jìn)行移位,在最高位(MSB)的位置補(bǔ)零,而最低位(LSB,移位后已經(jīng)被移出CRC寄存器)如果為1,則把寄存器與預(yù)定義的多項(xiàng)式碼進(jìn)行異或,否則如果LSB為零,則無(wú)需進(jìn)行異或。重復(fù)上述的由高至低的移位8次,第一個(gè)8-bit數(shù)據(jù)處理完畢,用此時(shí)CRC寄存器的值與下一個(gè)8-bit數(shù)據(jù)異或并進(jìn)行如前一個(gè)數(shù)據(jù)似的8次移位。所有的字符處理完成后CRC寄存器內(nèi)的值即為最終的CRC值。<BR> 下面為CRC的計(jì)算過(guò)程:<BR> 1.設(shè)置CRC寄存器,并給其賦值FFFF(hex)。<BR> 2.將數(shù)據(jù)的第一個(gè)8-bit字符與16位CRC寄存器的低8位進(jìn)行異或,并把結(jié)果存入CRC寄存器。<BR> 3.CRC寄存器向右移一位,MSB補(bǔ)零,移出并檢查L(zhǎng)SB。<BR> 4.如果LSB為0,重復(fù)第三步;若LSB為1,CRC寄存器與多項(xiàng)式碼相異或。<BR> 5.重復(fù)第3與第4步直到8次移位全部完成。此時(shí)一個(gè)8-bit數(shù)據(jù)處理完畢。<BR> 6.重復(fù)第2至第5步直到所有數(shù)據(jù)全部處理完成。<BR> 7.最終CRC寄存器的內(nèi)容即為CRC值。<BR><BR>二、
循環(huán)冗余碼校驗(yàn)程序的編寫(xiě)<BR><BR> 明白了CRC校驗(yàn)碼的產(chǎn)生過(guò)程,編寫(xiě)起程序來(lái)就非常容易了。由于Visual
Basic的廣泛普及以及其在數(shù)據(jù)通訊中的重要地位,下面就以VB語(yǔ)言來(lái)編寫(xiě)CRC的生成程序,其它語(yǔ)言只需稍做修改即可。<BR> 編寫(xiě)CRC校驗(yàn)程序有兩種辦法:一種為計(jì)算法,一種為查表法。下面對(duì)兩種方法分別討論。<BR><BR> 1.計(jì)算法<BR> 計(jì)算法就是依據(jù)CRC校驗(yàn)碼的產(chǎn)生原理來(lái)設(shè)計(jì)程序。其優(yōu)點(diǎn)是模塊代碼少,修改靈活,可移植性好。其缺點(diǎn)為計(jì)算量大。為了便于理解,這里假定了三位數(shù)據(jù),而多項(xiàng)式碼為A001(hex)。<BR> 在窗體上放置一命令按鈕Command1,并添加如下代碼:<BR><BR> Private
Sub Command1_Click()<BR> Dim CRC() As Byte<BR> Dim d() As Byte
'待傳輸數(shù)據(jù)<BR> ReDim d(2) As Byte<BR> d(0) = 123<BR> d(1) =
112<BR> d(2) = 135<BR> CRC = CRC16(d)
'調(diào)用CRC16計(jì)算函數(shù)<BR> 'CRC(0)為高位<BR> 'CRC(1)為低位<BR> End
Sub<BR> 注意:在數(shù)據(jù)傳輸時(shí)CRC的低位可能在前,而高位在后。<BR><BR> Function CRC16(data() As
Byte) As String<BR> Dim CRC16Lo As Byte, CRC16Hi As
Byte 'CRC寄存器<BR> Dim CL As Byte, CH As
Byte '多項(xiàng)式碼&HA001<BR> Dim SaveHi As Byte, SaveLo As
Byte<BR> Dim i As Integer<BR> Dim Flag As Integer<BR> CRC16Lo =
&HFF<BR> CRC16Hi = &HFF<BR> CL = &H1<BR> CH =
&HA0<BR> For i = 0 To UBound(data)<BR> CRC16Lo = CRC16Lo Xor
data(i) '每一個(gè)數(shù)據(jù)與CRC寄存器進(jìn)行異或<BR> For Flag = 0 To 7<BR> SaveHi =
CRC16Hi<BR> SaveLo = CRC16Lo<BR> CRC16Hi = CRC16Hi \
2 '高位右移一位<BR> CRC16Lo = CRC16Lo \ 2 '低位右移一位<BR> If
((SaveHi And &H1) = &H1) Then '如果高位字節(jié)最后一位為1<BR> CRC16Lo =
CRC16Lo Or &H80 '則低位字節(jié)右移后前面補(bǔ)1<BR> End If
'否則自動(dòng)補(bǔ)0<BR> If ((SaveLo And &H1) = &H1) Then
'如果LSB為1,則與多項(xiàng)式碼進(jìn)行異或<BR> CRC16Hi = CRC16Hi Xor CH<BR> CRC16Lo =
CRC16Lo Xor CL<BR> End If<BR> Next Flag<BR> Next i<BR> Dim
ReturnData(1) As Byte<BR> ReturnData(0) =
CRC16Hi 'CRC高位<BR> ReturnData(1) =
CRC16Lo 'CRC低位<BR> CRC16 = ReturnData<BR> End
Function<BR><BR> 2.查表法<BR> 查表法的優(yōu)缺點(diǎn)與計(jì)算法的正好相反。為了便于比較,這里所有的假定與計(jì)算法的完全相同,都而在窗體上放置一個(gè)Command1的按鈕,其代碼部分與上面的也完全一致。下面只介紹CRC函數(shù)的編寫(xiě)源代碼。<BR><BR> Private
Function CRC16(data() As Byte) As String<BR> Dim CRC16Hi As
Byte<BR> Dim CRC16Lo As Byte<BR> CRC16Hi = &HFF<BR> CRC16Lo =
&HFF<BR> Dim i As Integer<BR> Dim iIndex As Long<BR> For i = 0
To UBound(data)<BR> iIndex = CRC16Lo Xor data(i)<BR> CRC16Lo =
CRC16Hi Xor GetCRCLo(iIndex) '低位處理<BR> CRC16Hi =
GetCRCHi(iIndex) '高位處理<BR> Next i<BR> Dim ReturnData(1) As
Byte<BR> ReturnData(0) = CRC16Hi 'CRC高位<BR> ReturnData(1) =
CRC16Lo 'CRC低位<BR> CRC16 = ReturnData<BR> End
Function<BR><BR> 'CRC低位字節(jié)值表<BR> Function GetCRCLo(Ind As Long) As
Byte<BR> GetCRCLo = Choose(Ind + 1, &H0, &HC1, &H81,
&H40, &H1, &HC0, &H80, &H41, &H1, &HC0,
&H80, &H41, &H0, &HC1, &H81, &H40, &H1,
&HC0, &H80, &H41, &H0, &HC1, &H81, &H40,
&H0, &HC1, &H81, &H40, &H1, &HC0, &H80,
&H41, &H1, &HC0, &H80, &H41, &H0, &HC1,
&H81, &H40, &H0, &HC1, &H81, &H40, &H1,
&HC0, &H80, &H41, &H0, &HC1, &H81, &H40,
&H1, &HC0, &H80, &H41, &H1, &HC0, &H80,
&H41, &H0, &HC1, &H81, &H40, &H1, &HC0,
&H80, &H41, &H0, &HC1, &H81, &H40, &H0,
&HC1, &H81, &H40, &H1, &HC0, &H80, &H41,
&H0, &HC1, &H81, &H40, &H1, &HC0, &H80,
&H41, &H1, &HC0, &H80, &H41, &H0, &HC1,
&H81, &H40, &H0, &HC1, &H81, &H40, &H1,
&HC0, &H80, &H41, &H1, &HC0, &H80, &H41,
&H0, &HC1, &H81, &H40, &H1, &HC0, &H80,
&H41, &H0, &HC1, &H81, &H40, &H0, &HC1,
&H81, &H40, &H1, &HC0, &H80, &H41, &H1,
&HC0, _<BR>&H80, &H41, &H0, &HC1, &H81, &H40,
&H0, &HC1, &H81, &H40, &H1, &HC0, &H80,
&H41, &H0, &HC1, &H81, &H40, &H1, &HC0,
&H80, &H41, &H1, &HC0, &H80, &H41, &H0,
&HC1, &H81, &H40, &H0, &HC1, &H81, &H40,
&H1, &HC0, &H80, &H41, &H1, &HC0, &H80,
&H41, &H0, &HC1, &H81, &H40, &H1, &HC0,
&H80, &H41, &H0, &HC1, &H81, &H40, &H0,
&HC1, &H81, &H40, &H1, &HC0, &H80, &H41,
&H0, &HC1, &H81, &H40, &H1, &HC0, &H80,
&H41, &H1, &HC0, &H80, &H41, &H0, &HC1,
&H81, &H40, &H1, &HC0, &H80, &H41, &H0,
&HC1, &H81, &H40, &H0, &HC1, &H81, &H40,
&H1, &HC0, &H80, &H41, &H1, &HC0, &H80,
&H41, &H0, &HC1, &H81, &H40, &H0, &HC1,
&H81, &H40, &H1, &HC0, &H80, &H41, &H0,
&HC1, &H81, &H40, &H1, &HC0, &H80, &H41,
&H1, &HC0, &H80, &H41, &H0, &HC1, &H81,
&H40)<BR> End Function<BR><BR> 'CRC高位字節(jié)值表<BR> Function GetCRCHi(Ind
As Long) As Byte<BR> GetCRCHi = Choose(Ind + 1, &H0, &HC0,
&HC1, &H1, &HC3, &H3, &H2, &HC2, &HC6,
&H6, &H7, &HC7, &H5, &HC5, &HC4, &H4,
&HCC, &HC, &HD, &HCD, &HF, &HCF, &HCE,
&HE, &HA, &HCA, &HCB, &HB, &HC9, &H9, &H8,
&HC8, &HD8, &H18, &H19, &HD9, &H1B, &HDB,
&HDA, &H1A, &H1E, &HDE, &HDF, &H1F, &HDD,
&H1D, &H1C, &HDC, &H14, &HD4, &HD5, &H15,
&HD7, &H17, &H16, &HD6, &HD2, &H12, &H13,
&HD3, &H11, &HD1, &HD0, &H10, &HF0, &H30,
&H31, &HF1, &H33, &HF3, &HF2, &H32, &H36,
&HF6, &HF7, &H37, &HF5, &H35, &H34, &HF4,
&H3C, &HFC, &HFD, &H3D, &HFF, &H3F, &H3E,
&HFE, &HFA, &H3A, &H3B, &HFB, &H39, &HF9,
&HF8, &H38, &H28, &HE8, &HE9, &H29, &HEB,
&H2B, &H2A, &HEA, &HEE, &H2E, &H2F, &HEF,
&H2D, &HED, &HEC, &H2C, &HE4, &H24, &H25,
&HE5, &H27, &HE7, &HE6, &H26, &H22, &HE2,
&HE3, &H23, &HE1, &H21, &H20, &HE0, &HA0,
&H60, _<BR>&H61, &HA1, &H63, &HA3, &HA2, &H62,
&H66, &HA6, &HA7, &H67, &HA5, &H65, &H64,
&HA4, &H6C, &HAC, &HAD, &H6D, &HAF, &H6F,
&H6E, &HAE, &HAA, &H6A, &H6B, &HAB, &H69,
&HA9, &HA8, &H68, &H78, &HB8, &HB9, &H79,
&HBB, &H7B, &H7A, &HBA, &HBE, &H7E, &H7F,
&HBF, &H7D, &HBD, &HBC, &H7C, &HB4, &H74,
&H75, &HB5, &H77, &HB7, &HB6, &H76, &H72,
&HB2, &HB3, &H73, &HB1, &H71, &H70, &HB0,
&H50, &H90, &H91, &H51, &H93, &H53, &H52,
&H92, &H96, &H56, &H57, &H97, &H55, &H95,
&H94, &H54, &H9C, &H5C, &H5D, &H9D, &H5F,
&H9F, &H9E, &H5E, &H5A, &H9A, &H9B, &H5B,
&H99, &H59, &H58, &H98, &H88, &H48, &H49,
&H89, &H4B, &H8B, &H8A, &H4A, &H4E, &H8E,
&H8F, &H4F, &H8D, &H4D, &H4C, &H8C, &H44,
&H84, &H85, &H45, &H87, &H47, &H46, &H86,
&H82, &H42, &H43, &H83, &H41, &H81, &H80,
&H40)<BR> End
Function<BR><BR> 以上程序在Win98,VB6下調(diào)試通過(guò)。</TD></TR></TBODY></TABLE></CENTER></DIV>
<TABLE border=0 cellPadding=0 cellSpacing=0 height=77 width="100%">
<TBODY>
<TR>
<TD height=55 width="100%">
<P align=center><A href="http://www.vbeden.com/"
target=_blank>VB編程樂(lè)園</A>版權(quán)所有<FONT color=#000080>©,1999-2000</FONT><FONT
color=#008000>
<SCRIPT>document.write("<a href=http://www.topcn.com/siteinfo.asp?UserName=vbeden&SiteType=0 target=_blank><img src=http://www1.topcn.com:8081/statistics.asp?vbeden&referURL="+escape(top.document.referrer)+"&curURL="+escape(top.document.URL)+"&imgStyle=0"+" width=1 height=1 border=0 alt='Top中文網(wǎng)站龍虎榜' ></a>");</SCRIPT>
</FONT><FONT color=#000080><BR></FONT>網(wǎng)頁(yè)設(shè)計(jì)制作:<FONT color=#000080><A
href="mailto:vbeden@21cn.com">木子</A></FONT></P></TD></TR>
<TR>
<TD height=22 width="100%">
<P align=center>
<SCRIPT>var tc_user="vbboshi";var tc_class="2";</SCRIPT>
<SCRIPT src="VB下如何編寫(xiě)CRC校驗(yàn)程序.files/stat.js"></SCRIPT>
</P></TD></TR></TBODY></TABLE></BODY></HTML>
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -