首页 > 开发 > 综合 > 正文

VB下如何编写CRC校验程序

2024-07-21 02:20:48
字体:
来源:转载
供稿:网友
随着计算机技术的不断发展,在现代工业中,利用微机进行数据通讯的工业控制应用得也越来越广泛。由于传输距离、现场状况等诸多可能出现的因素影响,计算机与受控设备之间的通讯数据常会发生无法预测的错误。为了防止错误所带来的影响,一般在通讯时采取数据校验的办法,而循环冗余码校验是最常用的校验方法之一。

一、循环冗余码校验原理

  循环冗余码校验英文名称为cyclical redundancy check,简称crc。它是利用除法及余数的原理来作错误侦测(error detecting)的。实际应用时,发送装置计算出crc值并随数据一同发送给接收装置,接收装置对收到的数据重新计算crc并与收到的crc相比较,若两个crc值不同,则说明数据通讯出现错误。

根据应用环境与习惯的不同,crc又可分为以下几种标准:

  ①crc-12码;

  ②crc-16码;

  ③crc-ccitt码;

  ④crc-32码。

  crc-12码通常用来传送6-bit字符串。crc-16及crc-ccitt码则用是来传送8-bit字符,其中crc-16为美国采用,而crc-ccitt为欧洲国家所采用。crc-32码大都被采用在一种称为point-to-point的同步传输中。

下面以最常用的crc-16为例来说明其生成过程。

  crc-16码由两个字节构成,在开始时crc寄存器的每一位都预置为1,然后把crc寄存器与8-bit的数据进行异或,之后对crc寄存器从高到低进行移位,在最高位(msb)的位置补零,而最低位(lsb,移位后已经被移出crc寄存器)如果为1,则把寄存器与预定义的多项式码进行异或,否则如果 lsb为零,则无需进行异或。重复上述的由高至低的移位8次,第一个8-bit数据处理完毕,用此时crc寄存器的值与下一个8-bit数据异或并进行如前一个数据似的8次移位。所有的字符处理完成后crc寄存器内的值即为最终的crc值。

  下面为crc的计算过程:

  1.设置crc寄存器,并给其赋值ffff(hex)。

  2.将数据的第一个8-bit字符与16位crc寄存器的低8位进行异或,并把结果存入crc寄存器。

  3.crc寄存器向右移一位,msb补零,移出并检查lsb。

  4.如果lsb为0,重复第三步;若lsb为1,crc寄存器与多项式码相异或。

  5.重复第3与第4步直到8次移位全部完成。此时一个8-bit数据处理完毕。

  6.重复第2至第5步直到所有数据全部处理完成。

  7.最终crc寄存器的内容即为crc值。

二、 循环冗余码校验程序的编写


  明白了crc校验码的产生过程,编写起程序来就非常容易了。由于visual basic的广泛普及以及其在数据通讯中的重要地位,下面就以vb语言来编写crc的生成程序,其它语言只需稍做修改即可。

  编写crc校验程序有两种办法:一种为计算法,一种为查表法。下面对两种方法分别讨论。


  1.计算法

  计算法就是依据crc校验码的产生原理来设计程序。其优点是模块代码少,修改灵活,可移植性好。其缺点为计算量大。为了便于理解,这里假定了三位数据,而多项式码为a001(hex)。

  在窗体上放置一命令按钮command1,并添加如下代码:


  private sub command1_click()

   dim crc() as byte

   dim d() as byte ’待传输数据

   redim d(2) as byte

   d(0) = 123

   d(1) = 112

   d(2) = 135

   crc = crc16(d) ’调用crc16计算函数

   ’crc(0)为高位

   ’crc(1)为低位

  end sub

  注意:在数据传输时crc的低位可能在前,而高位在后。


  function crc16(data() as byte) as string

   dim crc16lo as byte, crc16hi as byte   ’crc寄存器

   dim cl as byte, ch as byte        ’多项式码&ha001

   dim savehi as byte, savelo as byte

   dim i as integer

   dim flag as integer

   crc16lo = &hff

   crc16hi = &hff

   cl = &h1

   ch = &ha0

   for i = 0 to ubound(data)

    crc16lo = crc16lo xor data(i) ’每一个数据与crc寄存器进行异或

    for flag = 0 to 7

     savehi = crc16hi

     savelo = crc16lo

     crc16hi = crc16hi / 2      ’高位右移一位

     crc16lo = crc16lo / 2      ’低位右移一位

     if ((savehi and &h1) = &h1) then ’如果高位字节最后一位为1

      crc16lo = crc16lo or &h80   ’则低位字节右移后前面补1

     end if              ’否则自动补0

     if ((savelo and &h1) = &h1) then ’如果lsb为1,则与多项式码进行异或

      crc16hi = crc16hi xor ch

      crc16lo = crc16lo xor cl

     end if

    next flag

   next i

   dim returndata(1) as byte

   returndata(0) = crc16hi       ’crc高位

   returndata(1) = crc16lo       ’crc低位

   crc16 = returndata

  end function

  2.查表法

  查表法的优缺点与计算法的正好相反。为了便于比较,这里所有的假定与计算法的完全相同,都而在窗体上放置一个command1的按钮,其代码部分与上面的也完全一致。下面只介绍crc函数的编写源代码。


  private function crc16(data() as byte) as string

   dim crc16hi as byte

   dim crc16lo as byte

   crc16hi = &hff

   crc16lo = &hff

   dim i as integer

   dim iindex as long

   for i = 0 to ubound(data)

    iindex = crc16lo xor data(i)

    crc16lo = crc16hi xor getcrclo(iindex)    ’低位处理

    crc16hi = getcrchi(iindex)          ’高位处理

   next i

   dim returndata(1) as byte

   returndata(0) = crc16hi    ’crc高位

   returndata(1) = crc16lo    ’crc低位

   crc16 = returndata

  end function


  ’crc低位字节值表

  function getcrclo(ind as long) as byte

   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, _

&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)

  end function


  ’crc高位字节值表

  function getcrchi(ind as long) as byte

   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, &had, &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, _

&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)

  end function


  以上程序在win98,vb6下调试通过。



作者blog:http://blog.csdn.net/huitiansou/
相关文章 字符串转换成十六进制
vb下如何编写crc校验程序
md5加密算法在vb中的实现
md5算法实现
md5算法研究


收集最实用的网页特效代码!

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表